2017-08-03 46 views
0

我創建了一個通用的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它只是一個存儲庫類,可以處理所有實體類型 –

回答

0

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

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