【问题标题】:Deleting multiple records with Entity Framework using a single LINQ query使用单个 LINQ 查询使用 Entity Framework 删除多条记录
【发布时间】:2012-01-16 10:33:13
【问题描述】:

我正在尝试使用将生成单个查询的 LINQ 执行删除。

这是我的做法:

// NorthwintEntities is an ADO.NET Entitity Data Model
var northwindEntities = new NorthwindEntities();
northwindEntities.Order_Details.Delete(o => o.Order_ID == 11076);

这是我的扩展:

public static class EntityExtensions
{
    private static Regex rxTableName = new Regex(@"^FROM\s+(?<table>\[[^\]]*\](\.\[[^\]]*\]){0,2})\s+AS\s+(?<alias>\[[^\]]*\])", RegexOptions.Multiline);

    public static void Delete<T>(this ObjectSet<T> entity, Expression<Func<T, bool>> expression) where T : EntityObject
    {
        var selectQuery = entity.Where(expression).Select(x => 1);

        string selectQueryString = ((ObjectQuery)selectQuery).ToTraceString();

        string deleteQueryString = ConvertSqlSelectToDelete(selectQueryString);

        entity.Context.ExecuteStoreCommand(deleteQueryString);
    }

    private static string ConvertSqlSelectToDelete(string selectQuery)
    {
        if (selectQuery.IndexOf(" JOIN ") > -1)
        {
            throw new Exception("Query with JOIN is not supported: " + selectQuery);
        }

        Match match = rxTableName.Match(selectQuery);
        if (!match.Success)
        {
            throw new Exception("Unable to convert SELECT: " + selectQuery);
        }

        string deleteQuery = "DELETE \r\n" + selectQuery.Substring(match.Index);
        deleteQuery = deleteQuery.Replace(match.Groups["alias"].Value + ".", "");
        deleteQuery = deleteQuery.Replace("AS " + match.Groups["alias"].Value, "");

        return deleteQuery;
    }
}

这可行,但我有几个 cmets。

  • 我不喜欢在这里使用 Regex,但这是我获得表名的唯一方法。 (entity.EntitySet.Name 不会总是返回正确的名称。[Order Details] 就是一个示例)。
  • 完成此操作后,我找到了此http://msmvps.com/blogs/matthieu/archive/2010/05/21/bulk-delete-v3.aspx,但仍无法使其正常工作。不断从为 null 的上下文中获取 NotImplementedException。
  • 使用连接删除似乎不起作用。我正在使用 SQL Server Compact 3.5 进行测试,也许这是一个限制。

所以我的问题是:有没有更简单的方法可以做到这一点?如果有,是什么?

任何帮助都将不胜感激。

【问题讨论】:

标签: c# linq entity-framework


【解决方案1】:
  1. 安装实体框架扩展库 (PM> Install-Package EntityFramework.Extended)

  2. 在您的代码中导入 EntityFramework.Extensions

  3. 删除内部查询指定的记录

    context.Orders.Where(o=>o.User_ID == 1).Delete();
    

删除用户 ID = 1 的订单中的所有记录

【讨论】:

  • 这不符合 EntityFramework 的精神,仅限于特定的提供程序 (SQL-Server)。
【解决方案2】:

批量删除的一种方法是在外键上设置 ON CASCADE DELETE。您需要在设计器中的关系上设置 CASCADE,并在数据库中的关系上设置 ON CASCADE DELETE。

要从 Order EF 中删除 Products 导航属性,将对数据库执行(产品属性数)+1 语句。

我更喜欢这样做:

var order = context.Orders.Include(p=>p.Products).Where(o=>o.Order_ID == 11076);

foreach(Product product in order.Products.ToList())
{
  context.Entry(product).State = EntityState.Deleted;
}
context.Entry(order ).State = EntityState.Deleted;
context.SaveChanges();

希望对你有帮助。

【讨论】:

  • 移动枚举中的下一个项目时,会出现错误“项目已从列表中修改,无法继续进行枚举。
  • 我不知道为什么@DOM 说它不起作用。只要您不要忘记调用 ToList() 方法,它就可以正常工作。
猜你喜欢
  • 1970-01-01
  • 2023-03-05
  • 2015-01-27
  • 2019-08-22
  • 2015-01-01
  • 2018-04-18
  • 1970-01-01
  • 2021-09-13
  • 1970-01-01
相关资源
最近更新 更多