实体框架格式化 DateTime SQL 参数,不带毫秒以实现乐观并发

2023-12-07

我正在尝试在实体框架中使用具有乐观并发性的 DateTime LastModifiedDate 列(可能会将其升级到 DateTime2。)我已将并发模式设置为固定。但是,当我检索实体、更改列并尝试保存时,出现并发异常。

存储的LastModifiedDate是2017-01-04 21:16:55.283但看看为更新生成的 SQL 实体框架:

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)

请注意,它传递了一个格式化的日期时间字符串@2其中不包括毫秒。当然,如果它没有传递与检索到的值相同的值,那么它就不匹配!我已经验证在运行时,.NET DateTime 确实包含 0.283 秒。请告诉我有一种方法可以传递完整的值。为什么它会这样,我怎样才能改变它以包括毫秒?


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

这不是发送的实际参数值。这只是日志记录,并且省略了小数秒。有一个问题,但不是这个。

如果您进行分析,您应该会看到类似这样的内容,其中显示了参数类型和值的详细信息。

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'

发生的情况是 datetime2(7) 值不是往返于日期时间之间转换的。最简单的解决方法就是对表列使用 datetime2(7) 。如果您想使用该列进行乐观并发控制,则无论如何都需要额外的精度。

所以像这样:

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();
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实体框架格式化 DateTime SQL 参数,不带毫秒以实现乐观并发 的相关文章

随机推荐