6
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)。自加载实体后,实体可能已被修改或删除。刷新 ObjectStateManager 条目。

4

2 回答 2

10

这很可能是 .NETDateTime类型和您在 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'

.NETDateTime存储小数点后 7 位数字:.5156250. 但是 SQLdatetime类型无法存储它,因为它的精度较低,并且在存储值后会截断一些数字。因此,子句[GroupDate] = @0中的比较返回并且 EF 得到没有存储任何内容的信息(尽管实际上已经执行了 INSERT ,取消事务并抛出异常。wherefalse

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

  • 从主键中删除GroupDate,即使其成为非键列
  • 或者将 SQL Server 中的列类型更改datetime2(7)为与 .NET 类型具有相同精度的列的DateTime类型
  • 或者为您GroupDate提供较低的精度,以便可以将值完全存储在 SQLdatetime类型中而不会被切断,例如只有秒精度和毫秒为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值中删除毫秒,但我现在找不到。)

于 2013-09-01T12:38:21.010 回答
1

不要关闭Optmistic 并发更新,您将隐藏问题而不是修复它。请执行下列操作:

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 的不同之处我希望这能解决您的问题。

于 2013-09-01T11:16:13.973 回答