启用RemoveRange以通过实体上的谓词删除

时间:2015-06-03 14:33:00

标签: c# linq entity-framework linq-expressions

在业务层中,当删除与正在被删除的实体的关系时,存在大量重复代码(没有数据库上的级联删除的好处)。除了相关实体删除用例之外,还可以使用一种好的方法来减少通过任何匹配谓词删除记录所需的代码,例如通过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);

我将此问题作为Q& A发布,并提供了我想出的解决方案,以便我以后可以查找。绝对希望看到其他方法。

3 个答案:

答案 0 :(得分:2)

一种方法是使用表达式在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);
    }
}

使用此扩展程序后,现在可以类似于Where调用RemoveRange。

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

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:1)

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

我无法记住语法,但与

类似
context.Phones.Delete(p => p.PersonId == personId)  

此LINQ语句变为

DELETE FROM Phones WHERE PersonId = ?

https://github.com/loresoft/EntityFramework.Extended