I'm facing a puzzle regarding the entity framework. Using mvc 4 and entity framework 5.0, I am developing an addon to an existing application which has the following table names:
dbo.company1_contact
dbo.company1_product
dbo.company2_contact
dbo.company2_product
..
A user generally only has access to either company one or company two, and I want to support users of all companies. This calls for a generic approach.
So I created two edmx files, one for company 1, and one for company 2, using the same entity and context names. Resulting in classes such as
Entities.Company1.Contact
Entities.Company1.Product
Entities.Company2.Contact
Entities.Company2.Product
and two context classes:
Entities.Company1.Company1Entities
Entities.Company2.Company2Entities
This is not enough to be able to use it in a generic way because for instance, the controller would need a repository variable such as:
private Company1Entities db = new Company1Entities()
and for company 2 this would be
private Company2Entities db = new Company2Entities()
The generic approach would be to use an interface ICompanyEntities and a factory to get the correct repository. BUT - the contained DbSet properties in the context classes may have the same name, they are not of the same type. To be specific, for instance the products set in the context classes is now defined as
DbSet<Entities.Company1.Product> Products {}
versus
DbSet<Entities.Company2.Product> Products {}
So I modified the T4 templates to generate an interface for each type, have each entity implement that interface, and generate each context class as containing the dbset with that interface, eg
public interface IRepository {}
public interface IContact {}
public interface IProduct {}
for each company:
public class Product : IProduct {}
and in the context classes:
public class Company1Entities : DbContext, IRepository
{
...
public DbSet<IProduct> Products { get; set; }
public DbSet<IContact> Contacts { get; set; }
}
This compiled fine, and I was hopeful the problem was solved. But the entity framework choked on it big time so I had to roll back entirely.
I then tried to use use the dynamic keyword for the db variable but linq won't accept that. Can someone explain me how to solve this issue? I am starting to feel that this is not possible with the entity framework, unless I write my controllers as partials and implement one controller for each company, containing only the line which declares the db variable. Which is something I really don't want to do, I'd rather duplicate the controller class entirely. Is there a solution, a generic approach? Am I missing something here? Help would be greatly appreciated.
This is not enough to be able to use it in a generic way- not really, thoseXXXEntitiesclasses derive fromSystem.Data.Entities.ObjectContext, therefore you could declare a member of that type and reference it.