实体框架共享核心功能库

本文关键字:心功能 核心 共享 框架 实体 | 更新日期: 2023-09-27 18:25:25

我正在编程一些项目,这些项目有一些相似的核心功能,然后还有它们自己的功能。

我正在考虑制作一个类库,使用代码优先的实体框架,以便提供一些共享功能和与之配套的数据库表

例如,我可能想使用类库发送电子邮件,然后使用实体框架登录发送电子邮件的数据库表。

这个类库将被添加到另一个项目中,该项目也在同一数据库中使用实体框架。因此,现在我希望数据库"自行构建",创建电子邮件日志记录表和其他一些功能,例如某种产品

我以前没有使用过实体框架,有两个dll会不会因为它们都指向同一个数据库但期望不同的表而导致任何形式的混乱?例如,他们会因为表没有出现在代码中而倾向于删除表吗?

如果我最终重叠了,也会引起问题吗?例如,如果我想对所有发送了电子邮件(类库实体框架)的产品(项目实体框架)进行联接,我能通过linq进行联接吗?

实体框架共享核心功能库

您需要将所有内容都保存在一个DbContext中。您可以使用接口对每个dll中的实体进行分组,然后声明一个具体的DbContext类,该类将所有实体组合在顶级代码中。

项目1:

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

项目2:

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将生成并维护一个数据库,即使您有可以独立操作的良好逻辑域竖井。

当您想要在思洛存储器实体之间执行联接时,您可以直接使用MyDbContext类进行编码。