我正在使用实体框架从表中删除几个项目。没有外键/父对象,所以我不能用OnDeleteCascade处理这个。

现在我正在做这个:

var widgets = context.Widgets
    .Where(w => w.WidgetId == widgetId);

foreach (Widget widget in widgets)
{
    context.Widgets.DeleteObject(widget);
}
context.SaveChanges();

它工作,但foreach困扰我。我使用EF4,但我不想执行SQL。我只是想确保我没有错过任何东西-这是最好的,对吧?我可以用扩展方法或helper来抽象它,但在某些地方我们还是要用foreach,对吧?


当前回答

对于任何使用EF5的人,可以使用以下扩展库:https://github.com/loresoft/EntityFramework.Extended

context.Widgets.Delete(w => w.WidgetId == widgetId);

其他回答

在EF 7中,您可以使用批量删除

    var ids = widgets.Select(x => x.Id).ToList();
    await _mrVodDbContext.Widgets.Where(x => ids.Contains(x.Id)).ExecuteDeleteAsync();

EF磁芯发生器

  DELETE FROM [i]
  FROM [Widgets] AS [i]
  WHERE [i].[Id] IN (4,3,2,1)

更多关于在发行说明中删除或更新的信息。https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-7.0/whatsnew#basic-executedelete-examples

如果你不想直接执行SQL,在循环中调用DeleteObject是最好的方法。

但是,您可以使用我在这里描述的方法,通过扩展方法执行SQL,并使其完全通用。

尽管答案是3.5。对于4.0,我可能会在底层使用新的ExecuteStoreCommand API,而不是下拉到StoreConnection。

我想出了一个很棒的库Zack.EFCore.Batch。它将您的表达式转换为简单的DELETE FROM ....在哪里查询。(就像一些建议的答案)https://github.com/yangzhongke/Zack.EFCore.Batch

使用示例:

等待ctx。DeleteRangeAsync<Book>(b => b. price > n);

Zack.EFCore.Batch库比Z.EntityFramework.Extended https://entityframework-extensions.net/有很多好处,后者没有真正的Async方法。(它们只是同步方法的包装)在高负载环境中使用这个库可能会遇到很多意想不到的问题。

EF 6.=>

var assignmentAddedContent = dbHazirBot.tbl_AssignmentAddedContent.Where(a =>
a.HazirBot_CategoryAssignmentID == categoryAssignment.HazirBot_CategoryAssignmentID);
dbHazirBot.tbl_AssignmentAddedContent.RemoveRange(assignmentAddedContent);
dbHazirBot.SaveChanges();

Thanh的回答最适合我。在一次服务器访问中删除了我所有的记录。我挣扎着实际调用扩展方法,所以我想分享我的(EF 6):

我将扩展方法添加到我的MVC项目中的一个助手类中,并将名称更改为“RemoveWhere”。我在控制器中注入了一个dbContext,但你也可以做一个using。

// make a list of items to delete or just use conditionals against fields
var idsToFilter = dbContext.Products
    .Where(p => p.IsExpired)
    .Select(p => p.ProductId)
    .ToList();

// build the expression
Expression<Func<Product, bool>> deleteList = 
    (a) => idsToFilter.Contains(a.ProductId);

// Run the extension method (make sure you have `using namespace` at the top)
dbContext.RemoveWhere(deleteList);

这将为组生成一条delete语句。