为什么我无法使用Entity Framework保存当前的DateTime.Now

时间:2013-09-01 10:33:21

标签: c# .net entity-framework

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(步骤= 1)而GroupDate不是

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

  

存储更新,插入或删除语句会影响意外   行数(0)。自那以后,实体可能已被修改或删除   实体已加载。刷新ObjectStateManager条目。

2 个答案:

答案 0 :(得分:9)

很可能是.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类型不能存储它,因为它的精度较低,并且在存储值后会切断一些数字。因此,[GroupDate] = @0子句中的比较where返回false,并且EF获取没有存储任何内容的信息(尽管INSERT实际上已执行) ,取消事务并抛出异常。

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

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

    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" }; 值中删除毫秒,而不是上面的代码,但我现在找不到。)

答案 1 :(得分:1)

请勿关闭 Optmistic Concurrency Updates ,否则您将隐藏问题而无法解决问题。执行以下操作:

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了,我希望这可以解决您的问题。