I have a table use id & DateTime column be the pk, but when I try to update data by Entity Framework like this:
using (Entities context = new Entities())
{
var item = (from item in context.BatchData
where item.Id == 2
select item ).FirstOrDefault();
item.Title = "EF6TEST";
context.SaveChanges();
}
I get an error
Store update, insert, or delete statement affected an unexpected number of rows (0).
After I recorded the SQL, I know the reason now.
The SQL looks like this
'update [dbo].[BatchData]
set [BatchData_Title] = @0
where (([BatchData_Id] = @1) and ([BatchData_CreatedDateTime] = @2))
select [BatchData_Rowversion]
from [dbo].[BatchData]BatchUploadData
where @@ROWCOUNT > 0 and [BatchData_Id] = @1 and [BatchData_CreatedDateTime] = @2',
N'@0 varchar(30),@1 tinyint,@2 datetime2(7)',
@0='EF6TEST',@1=1,@2='2017-09-16 11:29:35.3720000'
So, the reason is BatchData_CreatedDateTime
parameter in the SQL is @2='2017-09-16 11:29:35.3720000'
, the precision is 7 and it should be @2='2017-09-16 11:29:35.372'
.
And here is my question, How to fix it?
You can use IDbInterceptor
to change required data, here is an example of interceptor that changes type of parameters from DateTime2
to DateTime
, you can extend it to use it on a specific fields of your DB / DbCommand parameters.
public class DateInterceptor : IDbInterceptor, IDbCommandInterceptor
{
public void ReaderExecuting(DbCommand command,
DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
var dateParameters = command.Parameters.OfType<DbParameter>()
.Where(p => p.DbType == DbType.DateTime2);
foreach (var parameter in dateParameters)
{
parameter.DbType = DbType.DateTime;
}
}
To use it add DbInterception.Add(new DateInterceptor());
into the end of OnModelCreating
of your dbContext class
Generated SQL will be changed from
@2 datetime2(7)',@0=0,@1=1,@2='2017-09-24 14:41:33.7950485'
to
@2 datetime',@0=0,@1=1,@2='2017-09-24 14:40:32.327'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With