RepoDB: Bug: Cannot insert the value NULL into column
Bug Description
I am writing a quick&dirty method to import data from one instance of the database to another (same schema), but an exception is raised by target.BulkMergeAsync.
I am sure that there are no NULL values for Users_ID in the source data (see also the check below), but I am still getting the “Cannot insert the value NULL into column ‘Users_ID’” error.
Exception Message:
Microsoft.Data.SqlClient.SqlException: ‘Cannot insert the value NULL into column ‘Users_ID’, table ‘dbo.Users’; column does not allow nulls. UPDATE fails. The statement has been terminated.’
This exception was originally thrown at this call stack:
Microsoft.Data.SqlClient.SqlConnection.OnError(Microsoft.Data.SqlClient.SqlException, bool, System.Action<System.Action>) in SqlConnection.cs
Microsoft.Data.SqlClient.SqlInternalConnection.OnError(Microsoft.Data.SqlClient.SqlException, bool, System.Action<System.Action>) in SqlInternalConnection.cs
Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(Microsoft.Data.SqlClient.TdsParserStateObject, bool, bool) in TdsParser.cs
Microsoft.Data.SqlClient.TdsParser.TryRun(Microsoft.Data.SqlClient.RunBehavior, Microsoft.Data.SqlClient.SqlCommand, Microsoft.Data.SqlClient.SqlDataReader, Microsoft.Data.SqlClient.BulkCopySimpleResultSet, Microsoft.Data.SqlClient.TdsParserStateObject, out bool) in TdsParser.cs
Microsoft.Data.SqlClient.SqlCommand.InternalEndExecuteNonQuery(System.IAsyncResult, string, bool) in SqlCommand.cs
Microsoft.Data.SqlClient.SqlCommand.EndExecuteNonQueryInternal(System.IAsyncResult) in SqlCommand.cs
Microsoft.Data.SqlClient.SqlCommand.EndExecuteNonQueryAsync(System.IAsyncResult) in SqlCommand.cs
[External Code]
Code:
var count = 0;
var users = new List<User>();
if (string.IsNullOrEmpty(sourceconnectionstring) || string.IsNullOrEmpty(targetconnectionstring))
{
throw new ArgumentException("sourceconnectionstring and targeconnectionstring must be valid connection strings");
}
using (var source = new SqlConnection(sourceconnectionstring))
{
users = (await source.QueryAllAsync<User>().ConfigureAwait(false)).ToList();
}
if (users.Count > 0 && users.All(i => i.Users_ID != null))
{
using (var target = new SqlConnection(targetconnectionstring))
{
count = await target.BulkMergeAsync(users, qualifiers: p => new { p.Users_ID }, hints: SqlServerTableHints.TabLock, bulkCopyTimeout: 0).ConfigureAwait(false);
}
}
return count;
Schema and Model:
Please share to us the schema of the table (not actual) that could help us replicate the issue if necessary.
USE [Test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Users](
[Users_ID] [int] NOT NULL,
[Users_USERNAME] [varchar](50) NOT NULL,
[Users_PASSWORD] [varchar](50) NOT NULL,
[Users_NAME] [varchar](50) NOT NULL,
[Users_SURNAME] [varchar](50) NOT NULL,
[Users_MAIL] [varchar](100) NULL,
[Users_EXTENSION] [varchar](10) NOT NULL,
[Users_SITE_ID] [int] NOT NULL,
[Users_EXTERNAL] [bit] NOT NULL,
CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED
(
[Users_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
And also the model that corresponds the schema.
[Table("[dbo].Users")]
public class User
{
public int Users_ID { get; set; }
public string Users_USERNAME { get; set; }
public string Users_PASSWORD { get; set; }
public string Users_NAME { get; set; }
public string Users_SURNAME { get; set; }
public string Users_MAIL { get; set; }
public string Users_EXTENSION { get; set; }
public int Users_SITE_ID { get; set; }
public bool Users_EXTERNAL { get; set; }
}
Library Version:
RepoDb version=“1.12.9” RepoDb.MySql version=“1.1.5” RepoDb.SqlServer version=“1.1.5-beta1” RepoDb.SqlServer.BulkOperations version=“1.1.6-beta1”
targetFramework=“net48”
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 27 (11 by maintainers)
Thank you, I closed this issue as the problem is not caused by RepoDB and flushing the cache(s) makes everything works as expected.
NOTE: I don’t know if it makes sense to add some details to the RepoDB documentation about the fact that it is up to developer to either clear the cache or use different models in case of differences (also very slight ones) when the same model is used for multiple database providers (in my case there was an exception, but I don’t know if subtle bugs could be introduced in similar scenarios).
Thanks for helping us identifying the root cause. We will not make any further action on this.
For the model that is being used for multiple database providers, it is recommended to flush the caches (like what you did with your scenario). However, this solution will not work if the data type of the source and destination is not coerce(able) for the same property/field. This is only recommendable to the users that does not really like to create a separate model for source and destination RDBMS.
The information is enough for us to proceed with the fix. We will provide an update to you soon.