I am a .NET Developer and as part of a refactoring project, I have a few questions.
Our software is currently using an Active Record pattern (one to one mapping between the data objects and the business objects). The bad thing is that the business objects inherits from the data objects, inducing highly couple between the layers.
Our goal is to switch from our custom data access layer (based on ADO.NET) to Entity Framework. The constraint we have is not to break the code so that our older applications will still compile and run using the old data access layer while allowing us to use EF for the new projects.
My first idea to do so is to break the inheritance and have the data object as an attribute of the business object (and use an interface or abstract class in order to inject the data object, whether it is our custom layer or Entity Framework). The properties would be migrated from the Data objects to the business objects which would act like some kind of "proxy" to access the properties of the data objects.
Would that be a viable solution ? That would still use the active record pattern (and I don't like this a lot, since our business layer has become quite large) so if you have any other idea, please don't hesitate.
My other question is about the Entity framework generation. We need the entities properties to have the same name as the old data objects (we would use an abstract class in order to allow the business objects to call the properties of the data object, whether it is our custom data object or the EF entities). What would be the best way to accomplish that ? Using T4 to generate the entities or have an EF Code first approach ?
I am very open to any suggestio开发者_如何学编程n, so please do not hesitate to propose other approaches. Thanks for your time.
Would that be a viable solution ? If you would start a new project with Entity Framework I would say: No. Because Entity Framework is an implementation of the Repository and Unit Of Work pattern and Active Record pattern is a quite different approach.
Even if you use Non-POCO, EntityObject
derived entities with Entity Framework the entities don't become really active records because the persistence features which EntityObject
or EntityCollection
expose are limited (by design, I believe). EntityObject
just supports change tracking and EntityCollection
has functions like Load
or CreateSourceQuery
which support queries on that specific collection. But you don't have the full ObjectContext
at hand to issue arbitrary queries, delete objects or save changes.
EF 4.1 and DbContext
even don't support this anymore since EntityObject
derived entities are not allowed with DbContext
. It's a pure POCO approach with persistence unaware entities. There are only lazy loading and change tracking proxies which know the context, but that is only a "transparent" feature at runtime and you cannot program against this proxy context.
Now, you don't start with a new project but have an architecture you must respect in large parts. If your data object base classes (which implement Active Record) have methods like LoadMe
, SaveMe
, LoadCustomersContacts
, etc. and you use these methods in your business/service layers and you cannot or don't want to change this layer, then you probably have to find a working Active Record approach with Entity Framework.
This is a non-standard approach and a bit against the architecture of Entity Framework. It raises questions, for example: How do you manage context creation and lifetime in relation to object lifetime? How do you handle transactional and non-transactional behaviour? (SaveChanges
is a transaction by itself and you cannot save single "rows" or entities, you always save completely what's in the context/unit of work - modified, added or deleted. This is probably not the behaviour that your Active Record methods with ADO.NET have today.)
How to do that exactly? I don't know, I've never used this approach. Try to google for "Entity Framework and Active Record pattern" or something and perhaps you find a bit which doesn't say "Don't do that!".
To your other question: I'd prefer DbContext
with Code-First for the ease of development (that's what it was made for). But be aware that there are a few features which are not supported in Code-First and require an EDMX based solution ("Model-defined functions" is one of them, I believe, among others). Also mapping to Stored Procedures is not yet supported in DbContext
. You can issue raw SQL statements through the context though which can be a workaround for this limitation.
That's my view.
BTW: Welcome to Stackoverflow! Your question is problematic for the format of this site because too general and a bit asking for "opinions". I would recommend you to split your problem down into smaller parts and create separate smaller and more specific questions, perhaps decorated with little code snippets to make it more concrete and tangible. You usually get more response to such questions (and more valuable response than my blabla above). The good news is: You can create as many questions as you want.
精彩评论