converting POCO entity to business entity
Asked Answered
T

3

1

I am willing to integrate the entity framework as my data layer.

I followed articles and generated poco entities using this tutorial: http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the-entity-framework.aspx

I have my own business objects. Here is my business object Brach:

public class Branch
{
    public long BranchId { get; private set; }
    public string BranchName { get; set; }
    public string BranchCode { get; set; }

    public Branch() { }

    public void InsertBranch(Guid companyId)
    {
        using (var ctx = new Entities.Entities())
        {
            var branch = new T_STF_BRANCH() //This is generated POCO object
            {
                company_id = companyId,
                branch_name = BranchName,
                branch_code = BranchCode
            };
            ctx.T_STF_BRANCH.AddObject(branch);
            ctx.SaveChanges();
        }
    }

    public static IList<Branch> GetBranchesList(Guid companyId, long? branchId,
        string branchName)
    {
        using (var ctx = new Entities.Entities())
        {
            var branchs = ctx.T_STF_BRANCH.Where(x =>
                x.is_deleted == false &&
                (branchId == null || x.branch_id == branchId) &&
                (branchName == null || x.branch_name.Contains(branchName))).ToList();
        }
        //HERE I NEED SOMEHOW CONVERT THE POCO ENTITIES INTO MY BUSINESS ENTITIES...
    }
}

I don't know how to convert the POCO entity into my business entity.
Where should I put the conversion from POCO and to POCO?

Tapdance answered 16/4, 2011 at 17:3 Comment(0)
F
10

IMHO this is too complicated. Why do you have POCO entity for persistence and separate object for working with data loaded into POCO entity? Sounds like your application is over architectured.

ORM means object relational mapping. It means mapping between relation world and object world. Usually it can be also translated as mapping between database and your business objects. So you should use your POCO objects as your business objects. That is the whole meaning of using POCOs. If you don't want to use them as business objects you don't need them and you can use default entity objects directly.

If you want to use POCOs as business object simply let EF generate those POCOs for you and add partial class to each POCO defining your methods.

Btw. your business object actually looks like implementation of Active Record pattern. If you want to use this patterns perhaps you should check Windsor Active Record which is based on top of NHibernate.

Edit:

Well. You can use your classes instead of generated POCO entities.

One way is to give up with EFv4 and EDMX and check new EFv4.1 and its new fluent API (aka code-first) for mapping. This is whole for separate question or simply use search here on SO.

You can do that with EDMX as well. There are some basic rules which you have to follow to make this work because this whole is done by naming conventions. Because you already have classes you must modify this in EDMX file so that conceptual model is the same as your business objects:

  • Every business object which have to be saved or loaded must have entity in conceptual model
  • Entity must have the same name as the business object. You must also correctly set up the entity in property window (abstract, access level and base entity must be the same as in your business object)
  • Every stored property in the business object must have a property in the entity in conceptual model. Again you must correctly set up each property (getter and setter accessibility, type, nullable, etc).

EDMX consists of three layers:

  • SSDL - description of the database. This is almost always generated and you can't modify it directly in the designer.
  • CSDL - description of entities which must be the same as your business objects. This is what you modify in the designer. You can rename the fields as you want.
  • MSL - the mapping between SSDL and CSDL. If you open context menu on any entity in the designer you will see Table mapping. It will open a window with definition of mapping between CSDL and SSDL.

These are base rules but because you already have business objects you will most probably find situations where it will be hard to map it. The best way is simply to ask for that concrete issue. It will most probably be about some complex properties, navigation properties or inheritance.

Fatuous answered 16/4, 2011 at 18:16 Comment(8)
+1 I agree. I don't see the need to seperate them. It's also going to cause you some serious pain when you start loading relations etc, you'll end up building your own lazy loading etc, which is one of the major features of an or/m.Quasi
@Ladislav Mrnka: I have already my business entities. All my application is written using them. So I can't use POCO objects as my business objects. In the other hand, My business objects have inheritance and they are complex objects - unlike POCO. I am not sure I can use them instead of the POCO. I will really appriciate an example.Tapdance
@Naor: I edited my answer. This is to big to get you an example. You must show specific issue, something specific which you don't know how to map it to get a sample.Fatuous
@Ladislav Mrnka: Thanks for your answer. Can you take the example in my next question (#5690708) as a sample?Tapdance
@Ladislav Mrnka: I've read twice your answer but still don't get it. How can I map the db to my objects? changing member in the edmx will still map the field to the new member name?Tapdance
@Ladislav Mrnka: Thank you very much! I have more questions I'll ask later but you manage do put some light on the proccess.Tapdance
@LadislavMrnka If POCOs are business objects (businees layer) where does Repository pattern fit into this? Could the architecture be like this: DB->DAL(EF)->BLL(POCO)->Repository/Unit of Work->UI (MVP for instance)? Could You please shed some light?Underlaid
@LadislavMrnka Where does Business Layer/ POCO classes fit in this architecture? asp.net/media/2578149/…Underlaid
S
1

A couple possibilities here, if I understand you right.

You have your POCO entities that represent tables in your DB, and you have some business classes, or possibly even view models and you want to move from one to the other.

First possibility, in your business entities, create a constructor that takes your POCO entity as a parameter, then set up each property.

e.g.

public Branch (POCO poco)
{
  Name = poco.Name;
  Zip = poco.Zip;
}

Another option would be to use a tool like AutoMapper

It will help you auto map (hence the name ;) ) the two entities.

One thing I might suggest, is to not put Branch.GetListOfBranches(), but rather come up with a class like DataLayer.cs or something, put as much of your query logic in there. That way you don't have individual objects knowing about your data context, and when you need to make changes, there are fewer places to make them to.

We have a database called Sales, and our class is called SalesDb. We then use that class to retrieve the entities we need. So we might do a SalesDb.GetLeads(), or even a SalesDb.GetLeads(Filter f) to filter out what we don't need. Now the SalesDb is controlling the context and my Leads class doesn't need to know anything about it.

Squall answered 16/4, 2011 at 17:19 Comment(2)
Does your SalesDb class is actually the repository class?Tapdance
More or less, yes. We wrote a bunch of generic methods so we can do Filtering and sorting in the repository. We have Filter<T> where T can be any of our db models (we defined it via interfaces)Squall
B
1

If you are using the POCOs as an external data contract, you may want your model to you different entities/classes in order to prevent loose coupling between your external contracts and how your application works.

On retrieval of a data contract, you could retrieve the matching entity from the context, then inject values from the data contract into the entity/entities, using a tool such as ValueInjecter.

Buddhology answered 16/4, 2011 at 20:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.