【问题标题】:Entity Framework Delete All on Submit实体框架在提交时全部删除
【发布时间】:2011-01-09 19:30:36
【问题描述】:

在 LINQ to SQL 中,我可以这样做:

context.User_Roles.DeleteAllOnSubmit(context.User_Roles.Where(ur => ur.UserId == user.UserId));

实体框架的等效物是什么?

【问题讨论】:

标签: entity-framework


【解决方案1】:
foreach(var entity in context.User_Roles.Where(ur => ur.UserId == user.UserId))
{
  context.User_Roles.DeleteObject(entity);
}
context.SaveChanges();

当然,你可以写一个扩展方法,把它封装起来。

这将是这样的:

public static void DeleteObjects<TEntity> (this ObjectSet<TEntity> set, IEnumerable<TEntity> data) where TEntity : class
{
  foreach(var entity in data)
    set.DeleteObject(entity);
}

调用如下:

context.User_Roles.DeleteObjects(context.User_Roles.Where(ur => ur.UserId == user.UserId))
context.SaveChanges();

【讨论】:

  • 您可能会使用此方法遇到此问题,这应该会有所帮助:stackoverflow.com/a/3742340/183174
  • @nomad311 您提到的具体问题是什么?
  • 该问题的标题Can 't create extesion method for LINQ to Enitities link DeleteAllOnSubmit() in LINQ to SQL 是您遇到该问题时会收到的错误消息。
  • DeleteObjects 需要是静态的,TEntity 需要被约束到一个类:public static void DeleteObjects&lt;TEntity&gt;(this ObjectSet&lt;TEntity&gt; set, IEnumerable&lt;TEntity&gt; data) where TEntity : class
【解决方案2】:

@Femaref 的想法是正确的,但是对于 L2E 的 DeleteAllOnSubmit 的真正模拟,您需要您的扩展方法在枚举之前复制被删除的实体,这样您就不会在枚举”异常。

public static void DeleteAllObjects<TEntity>(this ObjectSet<TEntity> set, IEnumerable<TEntity> data) where TEntity : class {
    foreach(var entity in data.ToList()) //data.ToList() makes a copy of data for safe enumeration
        set.DeleteObject(entity);
}

【讨论】:

  • 这是我接受答案的问题。有没有比将整个集合拉入内存更有效的方法?
  • @Eric - 不是开箱即用的,您需要求助于自定义解决方案,也许以某种方式使用内联 SQL,但我没有尝试过类似的方法
  • 或者只是遍历数据使用:for (int i = data.Count() - 1; i &gt;= 0; i--) set.DeleteObject(data.ElementAt(i));
【解决方案3】:
foreach(var entity in context.User_Roles.Where(ur => ur.UserId == user.UserId))
{
  context.User_Roles.DeleteObject(entity);
}
context.SaveChanges();

当然,这个解决方案是可行的。但是,这是最低效的解决方案。 此解决方案将为每条记录(实体)生成一个删除 SQL 命令。 要删除 2000 年之前的所有数据的映像。数据库中有超过 1,000,000 条记录。如果以这种方式删除这些对象,将向服务器发送超过 1,000,000 条 SQL 命令,这是不必要的大浪费。 什么

【讨论】:

  • 您的答案看起来不完整。什么是另一种更有效的方法?
  • 我没有仔细阅读你的代码。但是,你为什么说“提交时删除所有”?这里的“ALL”是什么意思?
    如果要删除超过 2000 行甚至更多行的表中的所有数据,则必须使用 delete 语句而不是上面给出的答案。考虑到效率。
  • 不太可能有人会有这么多具有​​相同 UserId 的用户(它应该是一个主键,并且只有一个具有此 UserId 的用户)。不过我同意,对于大量实体,有更快的解决方案,例如 ExecuteStoreCommand stackoverflow.com/questions/869209/…
  • 是的,你是对的。我被标题迷惑了:提交时删除所有内容。
【解决方案4】:

Entity Framework 中没有 RemoveAll 等价物,因此您可以在内存中加载实体并使用 DeleteObject 方法将它们一一删除。

你可以使用 Linq : context.MyEntitie.RemoveAll(context.MyEntitie);

【讨论】:

    【解决方案5】:

    使用EntityFramework.Extensions
    1)首先使用NuGet安装EntityFramework.Extensions

    2)这里是类似于Linq2Sql的DeleteAllOnSubmit()的代码:

    using EntityFramework.Extensions;
    
    ....
    public void DeleteAllUsers(User_Role user){
       context.User_Roles.Delete(ur => ur.UserId == user.UserId);
       context.SaveChanges();
    }
    ...
    

    【讨论】:

    • 如果你将像 ur.UserID == user.UserId 这样的参数作为 bool 传递,你为什么不只传递一个 'true' 值 ;-) 这么干净,无论如何,这将始终是一个反模式.
    猜你喜欢
    • 2021-01-17
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    • 2012-11-24
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    相关资源
    最近更新 更多