2014-10-03 28 views
0

我正在編寫一些項目,它們具有一些類似的核心功能,然後是他們自己的功能。實體框架共享核心功能庫

我正在考慮製作一個類庫,在Code First中使用Entity Framework來提供一些共享功能和數據庫表。

例如,我可能希望使用類庫發送電子郵件,然後使用實體框架登錄發送電子郵件的數據庫表。

該類庫將被添加到另一個項目中,該項目也使用實體框架 - 在同一個數據庫中。因此,現在我希望數據庫能夠「自行構建」,創建電子郵件日誌記錄表和一些其他功能,例如某種產品。

我之前沒有使用過Entity Framework,會不會有兩個dll導致任何混淆,因爲它們都指向同一個數據庫,但期望不同的表?例如他們是否傾向於刪除表格,因爲它們沒有出現在代碼中?

如果最終重疊,它也會引起問題嗎?如果我想對已發送電子郵件(類庫實體框架)的所有產品(項目實體框架)進行連接,我是否可以通過linq進行連接?

+1

爲什麼不只是有一個「數據庫」項目,徹底封裝您訪問特定數據庫的所有數據,並在項目之間共享? – 2014-10-03 15:08:17

+0

問題是可能有60-80%的數據是相同的,但每個項目的列表和表格會有差異 - 以及查詢(一個項目比另一個項目更復雜)。因此,如果我要使用單個數據庫項目,那麼我需要爲每個項目提供多餘的表格,列和查詢。 – McGaz 2014-10-03 15:14:27

+0

但是你問,「將會有兩個DLL最終導致任何混亂,因爲它們都指向同一個數據庫」。如果不同的項目對於同一個表有不同的列,你怎麼能指向* same *數據庫呢? – 2014-10-03 15:16:29

回答

0

你會想保持在一個DbContext。你可以通過使用接口來對每個dll中的實體進行分組,然後聲明一個具體的DbContext類,將它們全部結合到頂級代碼中。

PROJECT1:

public interface IMyProj1DbContext : IDbContext 
{ 
    DbSet<Person> People { get; set; } 
    DbSet<Place> Places { get; set; } 
} 

Project2的:

public interface IMyProj2DbContext : IDbContext 
{ 
    DbSet<Customer> Customers { get; set; } 
    DbSet<Order> Orders { get; set; } 
} 

你還需要第三個項目定義普通會員:

public interface IDbContext 
{ 
    int SaveChanges(); 
} 

現在在代碼中所有這些走到一起,你可以聲明一個DbContext類來實現所有的接口:

public class MyDbContext : DbContext, IMyProj1DbContext, IMyProj2DbContext 
{ 
    public DbSet<Person> People { get; set; } 
    public DbSet<Place> Places { get; set; } 
    public DbSet<Customer> Customers { get; set; } 
    public DbSet<Order> Orders { get; set; } 
} 

現在,您將需要編寫使用兩種不同上下文的代碼,並且該代碼將存放在每個上下文的單個dll中。但你怎麼能這樣做?

public class PersonFinder 
{ 
    public Person FindPersonByLocation(Place placeToSearch) 
    { 
     using (var db = new ???) 
     { 
      return db.People.SingleOrDefault(p => p.Location_Id == placeToSearch.Id); 
     } 
    } 
} 

不能引用具體DbContext這裏,因爲這將導致循環依賴。最關鍵的是在運行時注入DbContext對象:

public class PersonFinder : Disposable 
{ 
    IMyProj1DbContext _db; 

    public PersonFinder(IMyProj1DbContext db) 
    { 
     _db = db; 
    } 

    public Person FindPersonByLocation(Place placeToSearch) 
    { 
     return _db.People.SingleOrDefault(p => p.Location_Id == placeToSearch.Id); 
    } 

    public void Dispose() 
    { 
     // ... Proper dispose pattern implementation excluded for brevity 
     if (_db != null && _db is Disposable) 
      ((Disposable)_db).Dispose(); 
    } 
} 

*這不是注入一次性對象,順便的最佳途徑。但這樣做是相對安全的,它證明了原理沒有額外的混亂。

現在,您只有一個DbContext,EF將生成並維護單個數據庫,即使您擁有可以獨立運行的良好邏輯域孤島。

當你想在silo實體之間執行連接時,你的代碼可以直接使用MyDbContext類。