2

In our application we are upgrading the existing DAL from EF 4.0 to EF 5.0.
Currently a generic repository pattern is already implemented and we are using POCO objects as business entities.
These objects are decorated with WCF attributes, since they are passed in web services interfaces and are extended with partial classes in order to add further business and validation methods. Moreover each POCO entity inherits from a base class "BusinessEntity" and interface "IBusinessEntity" in order to use generics repository methods easily.

We are planning to decouple the business entities from POCOs objects in order to make the latter as plain classes with only properties and no logic.

However after reading about the topic, it seems the current state of art is to adopt Code First approach and persist domain entities directly (even if of course it is not possible to generalize for all cases).
Related answer 1, related answer 2.

In our case, would it make sense to keep POCO objects with business logic in them and apply just the changes related to EF 5.0 (DbContext)? Or rather we should introduce a mapping layer inside the repository? In this way the application would work on the business entities and the repository layer would hide the POCOs object from outside. However the downside is the introduction of complexity, expecially when dealing with generic repository.

Thanks in advance.

Community
  • 1
  • 1
Francesco
  • 9,947
  • 7
  • 67
  • 110
  • 1
    I had a similar issue a while back, perhaps some of the answers may be of use to you: http://stackoverflow.com/questions/11521192/placement-of-dto-poco-in-a-three-tier-project – GrandMasterFlush Aug 28 '13 at 14:09
  • Thanks GrandMasterFlush for the post. Can I however ask you which approach did you use to map the business objects from POCOs? (if at the end you wne for this decision). – Francesco Aug 28 '13 at 15:23
  • I used the controller classes called by the WCF service which read the EF model and passed the data in the POCOs which were marked with the WCF attributes. As it wasn't a very big web site this seemed to make sense. – GrandMasterFlush Aug 28 '13 at 15:47
  • 1
    I am not sure if this approach might fit our scenario. We have two big systems: Frontend (MVC 4 application with provider and business layer) connected via WCF to the Backend (Code libraries implementing buiness layer, DAL and Service layers). In the frontend there is already a mapping between POCOs coming from the BE and we will not change it for the moment. We would focus on the BE objects, therefore working directly with EF there. – Francesco Aug 29 '13 at 06:26

1 Answers1

1

I want to share with you my experience regarding your question, although I came here finding a solution to another, related, problem.

Most of the people and articles I read are saying to use EF POCOs as business objects... To me, it looks like EF drives this tendency because if you want to decouple them, it could make the development more complex.

You said, you have already EF with POCOs in your system. Well, I want you to see it from the opposite angle: We have a project where, in the beginning, DAL used our own basic 'database handler' written with pure ADO.NET, and our own business classes; but now we try to support Entity Framework as well, in addition (so we load either old db handler or EF... maybe later we will switch to EF). Since we want to keep the database as is, we go database-first approach; for now we couldn't find a way to make an easier connection between our existing business objects and the POCOs (we use simple 'projection' for conversion at the moment).

So, in BL, the following preudo-code to insert one BObject1 which has a List<BObject2> (1:n relation) looks like this:

 this.UnitOfWork.ExecuteTransaction(() =>
 {
    bObject1_Repository.InsertBObject1(bObject1);

    foreach (var bObject2 in bObject1.ListBObject2)
       bObject2_Repository.InsertBObject2(bObject2);
 });

All is good for our old 'db handler'; we reuse same transaction and implicitly, same connection... But for EF now, gets very tricky. In order to insert any bObject2, first you may want to have maybe an auto-gen. UID for bObject1 (already known after first insert)... this is not available in EF, unless you call SaveChanges prematurely after first insert. As soon as more than one 'SaveChanges' calls are involved, you have to think what happens with these transactions. Distributed transactions (DTC) could be one hiccup... this is the case with our project when we want to support Oracle databases... and actually we are stuck here.

I hope I could help you see things from another angle as well...

Aside note:

Would be nice to hear opinions of someone experienced in EF and Oracle regarding usage of transactions in BL; it could help me with my question as well.

Community
  • 1
  • 1
Learner
  • 3,297
  • 4
  • 37
  • 62
  • Thanks Cristi for you post. We switched from Oracle to SQL Server two months ago. Before that date we had to use EF 4.0 due to compatibility issues. Our current architecture is the same as it was with Oracle, but now we are trying to upgrade it to EF 5.0 and DbContext. – Francesco Aug 29 '13 at 12:31
  • @Luca: So you already used Oracle with EF and didn't have any problems regarding transactions escalating/spanning? Do you mind sharing the way you structured the BL to use DAL? – Learner Aug 29 '13 at 12:37
  • We did not have distributed transactions, so the complexity in that sense was very low. We had in some cases issues with nested transactions that we are trying now to avoid by introducing UnitOfWork pattern inside the DAL. BL works with the repository by passing objects of a generic interface, whose specific type is resolved at runtime via reflexion, allowing to have generic methods and reduce redoundancy. – Francesco Aug 29 '13 at 12:45
  • Quite interesting... When you had a BL function to insert multiple related entities with autogenerated id, what code did you have? Do you mind for 5 mins chat? – Learner Aug 29 '13 at 12:52
  • I realize now that you used navigation properties and that's why it worked for you... – Learner Aug 29 '13 at 13:36