【问题标题】:Can't delete a row using entity framework无法使用实体框架删除行
【发布时间】:2016-06-23 06:30:18
【问题描述】:

我遇到的问题是使用实体时无法删除行。我能够找到该行,但错误我得到下一个错误:

附加信息:存储更新、插入或删除语句 影响了意外数量的行 (0)。实体可能已经 自加载实体后修改或删除。看 http://go.microsoft.com/fwlink/?LinkId=472540 获取有关信息 理解和处理乐观并发异常。

我尝试在包管理器控制台中更新数据库,尝试了几种不同的删除记录的方法,但目前没有运气。自动迁移已启用。

下面是我目前尝试使用的代码。

   var ctx = new Context();
   ApplicationUser user = new ApplicationUser { UserName = myUsername };
   ctx.Users.Attach(user);
   ctx.Users.Remove(user);
   ctx.Entry(user).State = EntityState.Modified;
   ctx.SaveChanges();

感谢所有帮助。我已经为此苦苦思索了好几个小时了。

【问题讨论】:

  • UserNameApplicationUser 实体的主键吗?
  • @Dennis 不是。主要是Id。这是一个 uuid。
  • 这似乎是你有一个乐观并发异常你知道那是什么吗?您是否有 rowversion 库,或者您同时从多个 DbContexts 读取和写入?
  • @BassamAlugili 我不相信我有 rowversion 列。不过,我有可能有多个 dbcontexts。我不确定如何检查。
  • 这可能是一个副作用。我找到了这个信息:“我遇到了这个问题,它是由实体的 ID(键)字段未设置引起的。因此,当上下文去保存数据时,它找不到 ID = 0。一定要放置更新语句中的断点并验证实体的 ID 是否已设置。"

标签: c# sql entity-framework


【解决方案1】:

EF中删除实体的常用方法如下:

  • 使用DbSet<T> 定位实体。这可能是从集合中检索实体或将其附加到集合;
  • 致电DbSet<T>.Remove;
  • 致电DbContext.SaveChanges

由于ApplicationUser.UserName不是主键属性,所以需要查找实体。附加在这里没有意义 - DbSet<T>.Attach 告诉上下文将具有给定主键的实体视为现有且未修改,但您没有设置主键值(可能是在构造函数中生成,因为您正在使用GUID?)。

类似这样的:

// assuming, that user names are not unique
var user = ctx.Users.FirstOrDefault(_ => _.UserName == myUsername);
if (user != null)
{
    ctx.Users.Remove(user);
    cts.SaveChanges();
}

【讨论】:

  • 这工作 100%。谢谢。我也很欣赏这个逻辑。如果它是主键,我可以附加它吗?
  • @alphamalle:如果您的代码将主键属性设置为某个现有值,它会在附加并调用Remove 后从数据库中删除实体。
【解决方案2】:

您删除您的实体,然后将其标记为已修改。删除行:

ctx.Entry(user).State = EntityState.Modified;

【讨论】:

    【解决方案3】:

    怎么样:

       var ctx = new Context();
       ApplicationUser user = new ApplicationUser { UserName = myUsername };
       ctx.Entry(user).State = EntityState.Deleted
       ctx.SaveChanges();
    

    或者只是删除有关修改记录的行。它不是必需的,因为首先您正在删除它而不是更改。其次,.Remove 函数已经将其设置为正确的状态。

    【讨论】:

    • 也许实际上没有匹配 UserName = myUsername 的记录?调试你的代码。检查 myUsername 变量值并确保数据库中存在 UserName = myUsername 的记录。
    • @我能够确认它已成功找到匹配的记录。我可以看到对象的所有属性。
    • 但是这个函数在数据库中没有找到记录:ApplicationUser user = new ApplicationUser { UserName = myUsername }; .它正在创造一些看起来像你的记录的东西。您是否在您的数据库中查找了该记录?
    • 正确我可以看到数据库中的记录,以及调试的时候。
    • 丹尼斯是正确的。非常感谢您抽出时间提供帮助。
    【解决方案4】:
      var ctx = new Context();
      ApplicationUser user =ctx.ApplicationUser.Where(c=>c.UserName == myUsername).FirstOrDefualt()
    

    您需要获取整条记录。否则,您需要填写所有Not Null

    【讨论】:

    • 这正是公认的答案所做的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-19
    相关资源
    最近更新 更多