我正在使用实体框架从表中删除几个项目。没有外键/父对象,所以我不能用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,对吧?
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语句。
在EF 6.2中,这可以很好地将删除直接发送到数据库,而无需首先加载实体:
context.Widgets.Where(predicate).Delete();
对于固定谓词,它非常简单:
context.Widgets.Where(w => w.WidgetId == widgetId).Delete();
如果你需要一个动态谓词,看看LINQKit (Nuget包可用),这样的东西在我的情况下工作得很好:
Expression<Func<Widget, bool>> predicate = PredicateBuilder.New<Widget>(x => x.UserID == userID);
if (somePropertyValue != null)
{
predicate = predicate.And(w => w.SomeProperty == somePropertyValue);
}
context.Widgets.Where(predicate).Delete();
在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