Entity Framework formats DateTime SQL parameter without milliseconds for optimistic concurrency

萝らか妹 提交于 2019-12-31 04:16:27

问题


I'm trying to use a DateTime LastModifiedDate column with optimistic concurrency in Entity Framework (will likely upgrade it to DateTime2.) I've set the Concurrency Mode to Fixed. But when I retrieve an entity, change a column and try to save, get a concurrency exception.

The stored LastModifiedDate is 2017-01-04 21:16:55.283 but look at the SQL Entity Framework is generating for the update:

UPDATE [dbo].[Facilities] 
SET [Password] = @0 
WHERE (([pk_FacilityID] = @1) AND ([LastModifiedDate] = @2)) 

-- @0: 'bz0dkK+smlat9psrIrbyXkxjpcXcDK1DeUiha7jCRkU=' (Type = String, Size = 255) 

-- @1: '6801bdcf-266d-46bd-b15e-dac21116208d' (Type = Guid) 

-- @2: '1/4/2017 9:16:55 PM' (Type = DateTime2)

Notice it's passing a formatted DateTime string for @2 which does not include milliseconds. Well of course it doesn't match if it's not passing in the same value it retrieved! I've verified that at runtime, the .NET DateTime does include the 0.283 seconds. Please tell me there's a way to pass in the full value. Why does it behave this way and how can I change it to include milliseconds?


回答1:


-- @2: '1/4/2017 9:16:55 PM' (Type = DateTime2)

That's not the actual parameter value sent. That's just the logging, and it leaves off the fractional seconds. There is a problem, but that's not it.

If you profile you should see something like this, that shows the details of the parameter type and value.

exec sp_executesql N'UPDATE [dbo].[Facilities]
SET [Name] = @0
WHERE (([FacilityId] = @1) AND ([LastModified] = @2))
',N'@0 nvarchar(max) ,@1 int,@2 datetime2(7)',@0=N'newName',@1=1,@2='2017-08-31 15:45:55.3030000'

What's happening is the datetime2(7) value is not round-trip converting to and back from datetime. And the easiest fix is just to use datetime2(7) for your table column. If you want to use the column for optimistic concurrency control, you need the extra precision anyway.

So something like this:

using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;

namespace Ef6Test
{
    public class Facility
    {
        public int FacilityId { get; set; }

        public string Name { get; set; }

        [ConcurrencyCheck(),Column(TypeName ="datetime2")]
        public DateTime LastModified { get; set; }
    }

    class Db : DbContext
    {
        public DbSet<Facility> Facilities { get; set; }


        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }

    }
    class Program
    {
        static void Main(string[] args)
        {
            Database.SetInitializer(new DropCreateDatabaseAlways<Db>());


            using (var db = new Db())
            {
                var f = db.Facilities.Add(new Facility() { LastModified = DateTime.Now, Name = "Faclity1" });
                db.SaveChanges();
            }
            using (var db = new Db())
            {
                var f = db.Facilities.First();
                f.Name = "newName";
                db.SaveChanges();
            }


            Console.ReadKey();
        }
    }
}


来源:https://stackoverflow.com/questions/45886733/entity-framework-formats-datetime-sql-parameter-without-milliseconds-for-optimis

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!