views:

156

answers:

3

Hello,

Recently I've read article "The Entity Framework In Layered Architecture" and there is written we can send EF-entities to client through WCF. But in many threads on Stackoverflow people tell that POCO(DTO)-objects should be used when we use WCF. And I have some questions.

  1. Why did Microsoft add DataContract attribute to EF-entities? Does Microsoft wanted us to use these objects everywhere in our applications? Or this is only for very simple applications and for rapid development?

  2. If I use POCO-objects, should I create auto generated EF-Entities, POCO-Entities and after that use any mapping library between them? Or I should use only POCO-objects in all components of my application?

  3. If I already have my own business entity, which has some methods, and it should be mapped to POCO object, on which layer should I convert POCO-object to my entity (for example, I have persistence layer, business logic layer, service layer(WCF), presenter layer (client, use WCF), UI layer)? Or I shouldn't make such my own entities?

Thanks in advance

+2  A: 

1.Why did Microsoft add DataContract attribute to EF-entities? Does Microsoft wanted us to use these objects everywhere in our applications? Or this is only for very simple applications and for rapid development?

Generally speaking, it is a bad idea to expose your EF-Entities in the service layer because that hardly couples your service layer and model representation. so any changes done in the model ends affecting directly your services, not a good idea. also you will have to version your service layer in some moment, so avoid to expose the EF entities in your service layer.

2.If I use POCO-objects, should I create auto generated EF-Entities, POCO-Entities and after that use any mapping library between them? Or I should use only POCO-objects in all components of my application?

You can use POCO objects inside your service layer, to decouple it from any underlying layers (see Automapper, to cover the Entity-DTO mapping cost). but you could still use the autogenerated EF-entities among the data and business layers in your architecture. just try to not rely in EF specific features of your generated domain model in other layers different from data layer. to ease the migration to another ORM frameworks.

If I already have my own business entity, which has some methods, and it should be mapped to POCO object, on which layer should I convert POCO-object to my entity (for example, I have persistence layer, business logic layer, service layer(WCF), presenter layer (client, use WCF), UI layer)? Or I shouldn't make such my own entities?

Service layer http://msdn.microsoft.com/en-us/library/ms978717.aspx. you would be using your domain model transparently among the server tier (persistence, business, service and presenter layers) of your application, and the only layer that will require you a DTO mapping is the service layer, see question 1. (additionally if you are using ViewModels inside your the presenter layer -nice idea- you will require to use POCOs-mapping in the presenter layer too).

SDReyes
I would suggest to sent POCOs to the client, except if there is a technology that requires you to do so (RIA services apparently does it, but I need to confirm that). So you would expose a cleanest service layer
SDReyes
Thanks a lot. And if I'll decide to change EF to other ORM, I should modify service layer also, right?
Pavel Belousov
Exactly. business and service layer. So you will not have to worry about populate and handle DTO up to the frontier of your solution, the Service Layer.
SDReyes
Thanks, but why I can't convent to DTO on business layer? I will be wrong architecture? It'll allow to change only business layer.
Pavel Belousov
I updated my answer being flexible in the performance overloading cost as a tradeoff for simplicity. and being more oriented to your question.
SDReyes
+3  A: 

You should read this article to see if EF with POCO suits you Working with POCO Entities (Entity Framework)

nemke
Thanks a lot for the article.
Pavel Belousov
+1  A: 

You can have POCO entities handwritten and completely separated from the persistence layer. SDReys is right, using generated EF entities as your model is smelly.

Here is the rough layout for a simple POCO model and the context to support it.

public class MyApplicationContext : ObjectContext, IMyApplicationContext {   
    public MyApplicationContext() : base("name=myApplicationEntities", "myApplicationEntities")  
    {
  base.ContextOptions.LazyLoadingEnabled = true;
        m_Customers = CreateObjectSet<Customer>();
        m_Accounts = CreateObjectSet<Account>();
    }

 private ObjectSet<Customer> m_Customers;
 public IQueryable<Customer> Customers {
        get { return m_Customers; }
    }
 private ObjectSet<Account> m_Accounts;
 public IQueryable<Account> Accounts {
        get { return m_Accounts; }
    }

 public Account CreateAccount(Customer customer) {
  var account m_Accounts.CreateObject();
  account.Customer = customer;
  return account;
 }
 public Customer CreateCustomer() {
  return m_Customers.CreateCustomer();
 }

 public void AddAccount(Account account) {
  m_Accounts.AddObject(account);
 }
 public void AddCustomer(Customer customer) {
  m_Customers.AddCustomer(customer);
 }
}

public class Account {
    public int Balance {get;set;}
    virtual public Customer{get;set;}
}

public class Customer {
    public string Name {get;set;}
    virtual public List<Account> Accounts{get;set;}
}
Igor Zevaka