你会想保持在一个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