你會想保持在一個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類。
爲什麼不只是有一個「數據庫」項目,徹底封裝您訪問特定數據庫的所有數據,並在項目之間共享? – 2014-10-03 15:08:17
問題是可能有60-80%的數據是相同的,但每個項目的列表和表格會有差異 - 以及查詢(一個項目比另一個項目更復雜)。因此,如果我要使用單個數據庫項目,那麼我需要爲每個項目提供多餘的表格,列和查詢。 – McGaz 2014-10-03 15:14:27
但是你問,「將會有兩個DLL最終導致任何混亂,因爲它們都指向同一個數據庫」。如果不同的項目對於同一個表有不同的列,你怎麼能指向* same *數據庫呢? – 2014-10-03 15:16:29