I am battling with dealing with how best to break a domain model up across multiple Visual Studio projects. I am working with EntityFramework 4 and Enterprise-type patterns to rationalise a system which can be reused for various applications. Eventually I want to end up with a set of mix-and-match DLL clas开发者_运维知识库s libraries which can be reused across web applications.
Sor far, I have a standard database schema which encompasses user information, a basic CRM, basic CMS and also a lightweight eCommerce platform.
The CRM / user tables are the core of the system. The CMS and eCommerce platforms utilise the CRM user tables. I want to define a core domain model from which the CMS and eCommerce domain models link/derive from.
So far, I have three visual studio projects:
- MyNamespace.Model.Core
- MyNamespace.Model.CMS
- MyNamespace.Model.Commerce
In each of these models is an Entity Framework Domain Model EDMX file. The EDMX contains all of the relevant tables for each. This means that the EDMX file for the CMS and Commerce projects contain some of the user tables. I could in theory have one big EF model and put all the POCOs in one class, but this isn't very extensible.
The projects also contain POCOs for each of the tables (these should probably be in a separate project but until things are sorted, they can stay where they are!).
When I come to use the domain model in a service layer with a Unit of Work, I only want to use one ObjectContext (this is actually an IObjectContext wrapper that targets the EF ObjectContext). For this reason, I have given each of the EDMX files the same Entity Container Name and namespace.
Questions:
- Is this the correct thing to do?
- If there are EF models in the same namespace with the same container name (albeit across different projects) will this cause problems if a table/entity is repeated (e.g. customers) in these different models?
Fair points, some comments:
This is the biggest problem as far as I can see. I guess it could be got round by using (for example) a CRM.Person where appropriate and a Commerce.Person where that is appropriate. I think what I am trying to get towards is a common POCO model with the EF domain model(s) sitting below that. I don't much care how the EF model(s) is built other than it should be structured sensibly.
Again, the next biggest problem. Solved to some degree by having duplicate entities in different contexts but then this would mean that some navigation properties are unavailable. For example a CRM.Person would not have the orders, shipping etc. properties that a Commerce.Person has even though they are the "same" person in the DB.
Reflection-based logic (at the moment) isn't important for me.
Agreed. Hence why I want to get towards one context somehow
The unit of work is actually an IUnitOfWork and is DI-ed into the repositories and needs to be independent of EF.
Disagree. The idea is to get towards a core application which can be extended if necessary. For example a future project may involve taking theatre bookings. This would be tied to the Commerce core but I would not want to reprogram the Commerce application to account for it. As far as I am concerned, rebuilding the EDMX models is not ideal. Might be the only way though.
- I can see how that could happen!
It seems at first glance as though this is a shortcoming of EF although there may be a very good reason for not doing what I want to do. Perhaps Microsoft should include some sort of method where two EDMX domain models with the same container name are merged at runtime. Effectively (and for want of a better word) the EDMX models would become "partial" and so long as there weren't any clashes I can't see too much wrong with this?
Well EF is very new and still almost everyone like you are experimenting and finding new ways to create better systems. So there will not be any straight forward answer but I can put my thoughts and my problems I have faced already.
Problems with multiple EDMX
- Sharing entities to build more generic logic will be difficult as you will end up having same named entities in multiple context.
- If they are going to be stored in one database, then in future you might need joins and relationships between two entities that are in different context.
- Writing reflection based generic logic will not be possible.
- Unit of work across multiple context will be complicated.
- EF already implements unit of work and RIA Services on top of it will be a good candidate instead of reimplementing whole thing.
- Keeping everything in one context will allow you to build extensible application. And mostly all the code will be auto generated so it will not make much of difference.
- We did try this and we realized that later on it needed lot of glue code and things became dirty as repetation of code and reports became big trouble and we finally moved everything in one context.
If I am going to store everything in one database, I see it as just one repository.
精彩评论