EF知识库 - 自定义删除方法
问题描述:
我创建了一个通用的EF知识库。对于每次删除,我需要检查我的实体是否有特定的接口,并在删除之前对其他实体做一些更改。我会怎么做?EF知识库 - 自定义删除方法
我试图创建一个像这样的foreach,但它不工作。
var entitiesToRemove = context.Set<TEntity>().Where(predicate).ToList();
foreach (var entityToRemove in entitiesToRemove)
{
///
}
我目前remove方法
public void Remove(Func<TEntity, bool> predicate)
{
context.Set<TEntity>()
.Where(predicate).ToList()
.ForEach(del => context.Set<TEntity>().Remove(del));
}
答
我相信你可以通过Strategy
模式
以下是只是一种可能的方法和示例解决这个问题。你不得不采取依赖注入考虑,以及(但你能适应这种想法)
/* Your Repository implementation would probably look like this */
public class GenericRepository<TEntity>
{
private readonly DbContext context;
private readonly RemoveStrategyFactory removeStrategyFactory;
public GenericRepository(DbContext context, RemoveStrategyFactory removeStrategyFactory)
{
this.context = context;
this.removeStrategyFactory = removeStrategyFactory;
}
public void Remove(Func<TEntity, bool> predicate)
{
var entitiesToRemove = context.Set<TEntity>()
.Where(predicate).ToList();
var removeStrategy = removeStrategyFactory.GetStrategy<TEntity>();
foreach (var entity in entitiesToRemove)
{
removeStrategy.BeforeRemove(entity);
context.Set<TEntity>().Remove(entity);
}
}
}
/* SAMPLE ENTITIES */
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public List<Order> Orders { get; set; }
}
public class Order
{
public int Id { get; set; }
public Customer Customer { get; set; }
public DateTime CreatedOn { get; set; }
public bool IsArchived { get; set; }
}
/* SAMPLE STRATEGIES and FACTORY */
public abstract class RemoveStrategy<TEntity>
{
public abstract void BeforeRemove(TEntity entity);
}
public sealed class DoNothingRemoveStrategy<TEntity> : RemoveStrategy<TEntity>
{
public override void BeforeRemove(TEntity entity)
{
// Do nothing
}
}
public sealed class CustomerRemoveStrategy : RemoveStrategy<Customer>
{
public override void BeforeRemove(Customer customer)
{
// Mark all orders as archived
foreach (var order in customer.Orders)
{
order.IsArchived = true;
}
}
}
public class RemoveStrategyFactory
{
private readonly Lazy<Dictionary<Type, object>> _lazyStrategyMap;
public RemoveStrategyFactory()
{
_lazyStrategyMap = new Lazy<Dictionary<Type, object>>(InitializeStrategyMap);
}
public RemoveStrategy<TEntity> GetStrategy<TEntity>()
{
var strategyMap = _lazyStrategyMap.Value;
object strategy;
if (strategyMap.TryGetValue(typeof(TEntity), out strategy))
{
return (RemoveStrategy<TEntity>) strategy;
}
return new DoNothingRemoveStrategy<TEntity>();
}
public Dictionary<Type, object> InitializeStrategyMap()
{
return new Dictionary<Type, object>
{
// CAREFUL: for Customer type, it must be a RemoveStrategy<Customer> or derived instance
{ typeof (Customer), new CustomerRemoveStrategy() }
};
}
}
+0
,您打到了靶心。感谢分享你的代码! –
做了'Remove'方法通用的,所以如果该项目有具体的接口,只能被调用。 – CodingYoshi
您是否拥有每个实体的抽象基础知识库类和具体知识库实现?或者它只是一个处理所有实体类型的存储库类? –
@AndrésRobinet它只是一个存储库类,可以处理所有实体类型 –