启用RemoveRange根据实体上的谓词进行删除

本文关键字:谓词 删除 RemoveRange 实体 启用 | 更新日期: 2023-09-27 17:53:09

在业务层中,当删除要删除的实体的关系时(没有对数据库进行级联删除的好处),会有很多重复的代码。除了相关的实体删除用例之外,还可以使用一种好的方法来减少通过任何匹配谓词(例如通过id或类似的谓词)删除记录所需的代码。

// Simple example removing phone numbers from people entity
// The "personId" is an identifier passed into the method performing the deletion
var phones = _context.Phones
    .Where(m => m.PersonId == personId)
    .ToList();
if (phones.Count > 0)
    _context.Phones.RemoveRange(phones);

我把这篇文章作为我想出的解决方案的问答,这样我就可以稍后查阅了。当然希望看到其他方法

启用RemoveRange根据实体上的谓词进行删除

一种方法是用表达式重载DbSet上的RemoveRange方法。为了使这尽可能方便,将其作为DbSet实体本身的方法扩展来实现,以便使用实际的RemoveRange方法简单地将进程重载到DbSet上。

public static class DataExtensions
{
    public static void RemoveRange<TEntity>(
        this System.Data.Entity.DbSet<TEntity> entities,
        System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate)
        where TEntity : class
    {
        var records = entities
            .Where(predicate)
            .ToList();
        if (records.Count > 0)
            entities.RemoveRange(records);
    }
}

有了这个扩展,RemoveRange现在可以像Where一样被调用。

_context.Phones.RemoveRange(m => m.PersonId == personId);

另一个选择是直接使用SQL:

context.Database.ExecuteSqlCommand("DELETE FROM Phones WHERE PersonId=@pid", personId) 

https://msdn.microsoft.com/en-us/library/gg679456%28v=vs.113%29.aspx

EF有一个扩展,可以在单个DML语句上对多个记录运行UPDATE和DELETE查询

我不记得语法了,但是和

很像
context.Phones.Delete(p => p.PersonId == personId)  

这个LINQ语句变成

DELETE FROM Phones WHERE PersonId = ?
https://github.com/loresoft/EntityFramework.Extended