为什么我无法保存当前日期时间.现在使用实体框架

本文关键字:实体 框架 时间 保存 当前日期 为什么 | 更新日期: 2023-09-27 18:29:58

using (var transaction = new TransactionScope())
{
     using (var db = new MyEntities())
     {    
          var newGroup = new Groups
          {
              GroupDate = DateTime.Now,
              GroupName = "someName"
          };
          db.Groups.Add(newGroup);
          db.SaveChanges();
     }
     transaction.Complete();
 }

GroupId 和 GroupDate 是 PK,GroupId 是 Identity(step = 1(,GroupDate 不是

任何人都可以告诉我为什么在使用这样的简单代码时会发生此异常以及如何关闭乐观并发更新(如果可能

(

存储更新、插入或删除语句受意外影响 行数 (0(。此后,实体可能已被修改或删除 实体已加载。刷新对象状态管理器条目。

为什么我无法保存当前日期时间.现在使用实体框架

这很可能是 .NET DateTime 类型和您在 SQL Server 中使用的列类型的不同精度的问题 - 可能datetime

使用 SaveChanges 发送到数据库的 INSERT 语句如下所示:

exec sp_executesql N'insert [dbo].[Groups]([GroupDate], [GroupName])
values (@0, @1)
select [GroupId]
from [dbo].[Groups]
where @@ROWCOUNT > 0 and [GroupId] = scope_identity() and [GroupDate] = @0',
N'@0 datetime2(7),@1 nvarchar(50)',
@0='2013-09-01 14:21:44.5156250',@1=N'someName'

.NET DateTime在小数点后存储 7 位数字:.5156250 。但是 SQL datetime 类型无法存储此值,因为它的精度较低,并且在存储值后会切断某些数字。因此,where 子句中的比较[GroupDate] = @0返回 false EF 获取未存储任何内容的信息(尽管实际执行 INSERT(,取消事务并引发异常。

据我所知,您只能通过以下更改之一来解决此问题:

  • 从主键中删除GroupDate,即将其设置为非键列
  • 或者将 SQL Server 中列的类型更改为与 .NET DateTime类型具有相同精度的 datetime2(7)
  • 或者为GroupDate提供较低的精度,以便该值可以完全存储在 SQL datetime 类型中而不会被切断,例如,仅具有秒精度和毫秒0

    var now = DateTime.Now;
    var date = new DateTime(now.Year, now.Month, now.Day,
                            now.Hour, now.Minute, now.Second);
    var newGroup = new Groups
    {
        GroupDate = date,
        GroupName = "someName"
    };
    

    (可能有一种比上面的代码更聪明的方法可以从给定的DateTime值中删除毫秒,但我现在找不到。

不要关闭乐观并发更新 您将隐藏问题而不是修复它。 执行以下操作:

using (var db = new MyEntities())
{    
    using (var transaction = new TransactionScope())
    {
        var newGroup = new Groups
        {
            GroupDate = DateTime.Now,
            GroupName = "someName"
        };
        db.Groups.Add(newGroup);
        db.SaveChanges();
        transaction.Complete();
     }
}

现在不同的是,您正在DBContext中创建TranscationScope,我希望这将解决您的问题。