在业务层中,当删除要删除的实体的关系时(没有对数据库进行级联删除的好处),会有很多重复的代码。除了相关的实体删除用例之外,还可以使用一种好的方法来减少通过任何匹配谓词(例如通过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);
我把这篇文章作为我想出的解决方案的问答,这样我就可以稍后查阅了。当然希望看到其他方法
一种方法是用表达式重载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