【问题标题】:Remove items that match memory objects with RemoveRange使用 RemoveRange 删除与内存对象匹配的项目
【发布时间】:2014-11-28 17:00:44
【问题描述】:

数据库中具有 1 列 (varchar) 的表:"user1","user2","user3"。

内存列表:users = {"user1","user2"}

是否有任何方法可以使用 RemoveRange 删除数据库中与内存列表中的项目匹配的项目?这样调用 SaveChanges() 后,user1 和 user2 就会从数据库中删除。

db.Users.RemoveRange(....);
db.SaveChanges();

谢谢

【问题讨论】:

    标签: c# linq entity-framework


    【解决方案1】:

    哎呀...完全忘记了实际答案。

    您想将项目“附加”到上下文中。

    List<User> usersToDelete = ...;
    foreach(var user in usersToDelete)
    {
        db.Users.Attach(user);
        db.Entry(user).State = EntityState.Deleted; 
    }
    db.SaveChanged();
    

    【讨论】:

    • 不,列表是一个内存对象,不是来自数据库,所以我们不能使用 Attach 因为它会因为相同的主键值而失败。
    • @qnguyen 你试过了吗?确保不要重复使用 DbContext,新建一个。
    【解决方案2】:

    您可以使用EntityFramework.Extensions 项目。

    List<User> usersToDelete = ...;
    List<int> idsToDelete = usersToDelete.Select(x => x.Id).ToList();
    db.Users.Delete(x => idsToDelete .Contains(x.Id));
    

    但是,如您所见,您必须在代码中定义键。可以创建和扩展从 EF 获取密钥...但是使用 System.Linq.Expressions 命名空间需要做很多工作,而且非常困难。

    【讨论】:

      【解决方案3】:

      使用 ORM 执行此操作的标准方法是从数据库中获取行(是的,我知道这很浪费),然后转身将其传递回删除函数。

      更好的方法是只进行原始 SQL 调用(不要忘记对其进行参数化)调用存储过程。


      var t = users.Select(x => x.ColumnName); 
      var t1 = db.TableName.Where(x => t.Contains(x.ColumnName)).ToList(); 
      //then call RemoveRange() 
      db.Ranges.RemoveRange(t1);
      

      【讨论】:

      • 感谢您的建议。我们如何从数据库中获取与内存列表匹配的数据?
      • 抱歉,您的代码不起作用,因为 VS 在 Contains() 处说无效参数我找到了这个链接。它可以帮助我获得匹配项:stackoverflow.com/questions/6547472/…var t = users.Select(x =&gt; x.ColumnName); var t1 = db.TableName.Where(x =&gt; t.Contains(x.ColumnName)).ToList(); //then call RemoveRange() db.Ranges.RemoveRange(t1);
      猜你喜欢
      • 2020-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-05
      相关资源
      最近更新 更多