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)); 
} 
+0

做了'Remove'方法通用的,所以如果该项目有具体的接口,只能被调用。 – CodingYoshi

+0

您是否拥有每个实体的抽象基础知识库类和具体知识库实现?或者它只是一个处理所有实体类型的存储库类? –

+0

@AndrésRobinet它只是一个存储库类,可以处理所有实体类型 –

我相信你可以通过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

,您打到了靶心。感谢分享你的代码! –