2012-12-14 28 views
0

我想創建一個基於實體類型的存儲庫。任何想法如何做到這一點?根據實體類型創建存儲庫

  • 我們有很多的實體,所以這需要是通用的代碼。
  • 我們需要爲每個實體擁有歷史表。
  • 我們使用代碼優先,DbContext,EF 5.0使用存儲庫和工作單元模式。

以下是我們必須在SaveChanges方法中更改的代碼。對於每個修改和刪除的實體,我們希望將舊行保存到歷史記錄表中。以下是針對單個實體的硬編碼:ServiceLocation

所有實體都有相應的歷史實體。例如,對於ServiceLocation實體,有一個ServiceLocationHistory實體(和存儲庫)。

如果修改實體的類型爲ServiceLocation,我該如何創建ServiceLocationHistoryRepository?併爲所有類型通用?

public override int SaveChanges() 
    { 
     // Get the entities that changed 
     var addedEntries = ChangeTracker.Entries().Where(e => e.State == EntityState.Added && e.Entity is IHistoryBase).Select(e => (TBaseEntity)e.Entity); 
     var modifiedEntries = ChangeTracker.Entries().Where(e => e.State == EntityState.Modified && e.Entity is IHistoryBase).Select(e => (TBaseEntity)e.Entity); 
     var deletedEntries = ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted && e.Entity is IHistoryBase).Select(e => (TBaseEntity)e.Entity); 

     // Debugging watch varibles 
     int x = addedEntries.Count(); 
     int y = modifiedEntries.Count(); 
     int z = deletedEntries.Count(); 

     // Create the Type adapter 
     TypeAdapter adapter = new TypeAdapter(new RegisterTypesMap[] { new HistoryRegisterTypesMap() }); 
     var serviceLocationHistoryRepository = new ServiceLocationHistoryRepository(this); 

     foreach (var addedEntry in addedEntries) 
     { 
      addedEntry.FromDate = DateTime.Now; 
      addedEntry.ToDate = DateTime.Parse("9999-12-31 00:00:00.0000000"); 
     } 

     foreach (var modifiedEntry in modifiedEntries) 
     { 

      ServiceLocationHistory history = adapter.Adapt<ServiceLocation, ServiceLocationHistory>(modifiedEntry as ServiceLocation); 
      serviceLocationHistoryRepository.Add(history); 

      history.FromDate = modifiedEntry.FromDate; 
      history.ToDate = modifiedEntry.FromDate = DateTime.Now; 
      modifiedEntry.ToDate = DateTime.Parse("9999-12-31 00:00:00.0000000"); 
     } 

     foreach (var deletedEntry in deletedEntries) 
     { 
      ServiceLocationHistory history = adapter.Adapt<ServiceLocation, ServiceLocationHistory>(deletedEntry as ServiceLocation); 
      serviceLocationHistoryRepository.Add(history); 

      history.FromDate = deletedEntry.FromDate; 
      history.ToDate = DateTime.Now; 
     } 
     return base.SaveChanges(); 

    } 

回答

0

下面是我用來根據類型獲取存儲庫的概念驗證碼。

 private dynamic GetHistoryRepository(TBaseEntity entry) 
    { 
     // TODO - How well does the below perform? 
     // TODO - Is there a way that we can only get one repository if there are multiple changed entities of the same type? 
     // TODO - How can we not hard code the type name? Put a property on each entity that gives us the entitys history repository? Factory? 

     // Get the History repository for the entity 
     Type objType = Type.GetType("Data.MainBoundedContext.CALMModule.Repositories." + entry.GetType().Name.Split('_')[0] + "HistoryRepository"); 
     return Activator.CreateInstance(objType, new object[] { this }); 
    }