2014-10-03 39 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类。