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

HB *_*AAM 6 .net c# 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();
 }
Run Code Online (Sandbox Code Playgroud)

GroupId和GroupDate是PK,GroupId是Identity(步骤= 1)而GroupDate不是

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

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

Sla*_*uma 10

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

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

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'
Run Code Online (Sandbox Code Playgroud)

.NET DateTime在小数点后存储7位数:.5156250.但是SQL datetime类型不能存储它,因为它的精度较低,并且在存储值后会切断一些数字.因此,相比[GroupDate] = @0where第收益false和EF获取信息后面什么也没有存储(虽然实际上INSERT 被执行),取消交易,并抛出异常.

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

  • GroupDate从主键中删除,即使其成为非键列
  • 或者将SQL Server中的列类型更改datetime2(7)为与.NET DateTime类型具有相同精度的列
  • 或者提供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"
    };
    
    Run Code Online (Sandbox Code Playgroud)

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

  • 我认为删除你提到的"毫秒"部分的更好的代码可能是:`var date = now.AddMilliseconds(-now.Millisecond);` (2认同)