我正在编写一些项目,这些项目具有一些相似的核心功能,然后是其自身的功能。
我正在考虑使用Entity Framework和Code First创建一个类库,以便提供一些共享功能和随之而来的数据库表。
例如,我可能想使用类库发送电子邮件,然后使用实体框架登录发送电子邮件的数据库表。
这个类库将被添加到另一个项目中,该项目也使用实体框架 - 在同一个数据库中。所以现在我希望数据库能够构建自己的#34;,创建电子邮件日志记录表和其他一些功能,例如:某种产品。
之前我没有使用Entity Framework,最终会有两个dll导致任何混乱,因为他们都指向同一个数据库,但期望不同的表?例如他们会倾向于删除表格,因为它们不会出现在代码中吗?
如果我最终重叠,它会导致问题,例如如果我想在已发送电子邮件(类库实体框架)的所有产品(项目实体框架)上进行加入,我是否可以通过linq进行加入?
答案 0 :(得分: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类。