我正面临有关实体框架的难题。使用 mvc 4 和实体框架 5.0,我正在开发一个现有应用程序的插件,该应用程序具有以下表名:
dbo.company1_contact
dbo.company1_product
dbo.company2_contact
dbo.company2_product
..
一个用户通常只能访问公司一或公司二,我想支持所有公司的用户。这需要一种通用的方法。
所以我创建了两个 edmx 文件,一个用于公司 1,一个用于公司 2,使用相同的实体和上下文名称。导致类如
Entities.Company1.Contact
Entities.Company1.Product
Entities.Company2.Contact
Entities.Company2.Product
和两个上下文类:
Entities.Company1.Company1Entities
Entities.Company2.Company2Entities
这不足以以通用方式使用它,因为例如,控制器需要一个存储库变量,例如:
private Company1Entities db = new Company1Entities()
对于公司 2,这将是
private Company2Entities db = new Company2Entities()
通用方法是使用接口 ICompanyEntities 和工厂来获取正确的存储库。但是 - 上下文类中包含的 DbSet 属性可能具有相同的名称,它们的类型不同。具体来说,例如在上下文类中设置的产品现在定义为
DbSet<Entities.Company1.Product> Products {}
相对
DbSet<Entities.Company2.Product> Products {}
所以我修改了 T4 模板为每种类型生成一个接口,让每个实体实现该接口,并生成每个上下文类作为包含具有该接口的 dbset,例如
public interface IRepository {}
public interface IContact {}
public interface IProduct {}
对于每家公司:
public class Product : IProduct {}
在上下文类中:
public class Company1Entities : DbContext, IRepository
{
...
public DbSet<IProduct> Products { get; set; }
public DbSet<IContact> Contacts { get; set; }
}
这编译得很好,我希望问题得到解决。但是实体框架严重阻塞了它,所以我不得不完全回滚。
然后我尝试对 db 变量使用 dynamic 关键字,但 linq 不会接受。有人可以解释我如何解决这个问题吗?我开始觉得实体框架不可能做到这一点,除非我将控制器编写为部分控制器并为每个公司实现一个控制器,只包含声明 db 变量的行。这是我真的不想做的事情,我宁愿完全复制控制器类。有解决方案,通用方法吗?我在这里错过了什么吗?帮助将不胜感激。