【问题标题】:Entity Framework in Layered Architectures分层架构中的实体框架
【发布时间】:2011-03-16 19:00:41
【问题描述】:

最近我阅读了文章“The Entity Framework In Layered Architecture”,其中写到我们可以通过 WCF 向客户端发送 EF 实体。但是在 Stackoverflow 上的许多线程中,人们告诉我们在使用 WCF 时应该使用 POCO(DTO) 对象。 还有一些问题。

  1. 为什么 Microsoft 将 DataContract 属性添加到 EF 实体? Microsoft 是否希望我们在应用程序的任何地方都使用这些对象?或者这只适用于非常简单的应用程序和快速开发?

  2. 如果我使用 POCO 对象,我是否应该创建自动生成的 EF 实体、POCO 实体,然后在它们之间使用任何映射库?或者我应该在我的应用程序的所有组件中只使用 POCO 对象?

  3. 如果我已经有自己的业务实体,它有一些方法,并且应该映射到POCO对象,我应该在哪一层将POCO-object转换为我的实体(例如,我有持久层,业务逻辑层,服务层(WCF),展示层(客户端,使用WCF),UI层)?或者我不应该让这样的实体成为我自己的实体?

提前致谢

【问题讨论】:

  • 请记住,这篇文章是 2 年前写的。从那时起,许多事情都发生了变化。 EF 4.0 带来了一些新特性,可以与 poco 一起使用,更好地与 wcf 一起使用等等。
  • 你应该阅读这篇文章,看看EF和POCO是否适合你Working with POCO Entities (Entity Framework)
  • 非常感谢这篇文章。
  • 是的,我明白了。我只是尝试决定如何开发我的应用程序。
  • 请问您在 UI 层中使用的是什么?

标签: c# .net entity-framework poco


【解决方案1】:

1.微软为什么要添加DataContract 归因于 EF 实体?做 微软希望我们使用这些 我们身边到处都是物体 应用程序?或者这只是为了非常 简单的应用程序和快速 发展?

一般来说,在服务层中公开 EF 实体是一个坏主意,因为这很难将服务层和模型表示耦合在一起。因此模型中所做的任何更改最终都会直接影响您的服务,这不是一个好主意。您还必须在某个时候对服务层进行版本控制,因此请避免在服务层中公开 EF 实体。

2.如果我使用 POCO 对象,我应该创建自动生成的 EF 实体吗? POCO-实体,然后使用任何 它们之间的映射库?或者我 应该只使用 POCO 对象 我的应用程序的组件?

您可以在服务层中使用 POCO 对象,将其与任何底层层分离(请参阅 Automapper,以涵盖 Entity-DTO 映射成本)。但您仍然可以在架构中的数据和业务层之间使用自动生成的 EF 实体。只是尽量不要依赖与数据层不同的其他层中生成的域模型的 EF 特定功能。以简化向其他 ORM 框架的迁移。

如果我已经有自己的生意 实体,它有一些方法,它 应该映射到 POCO 对象,在 我应该转换哪一层 POCO 对象到我的实体(例如, 我有持久层,业务 逻辑层、服务层(WCF)、 演示者层(客户端,使用 WCF),UI 层)?或者我不应该这样 拥有实体?

服务层http://msdn.microsoft.com/en-us/library/ms978717.aspx。您将在应用程序的服务器层(持久层、业务层、服务层和演示层)之间透明地使用域模型,并且唯一需要 DTO 映射的层是服务层,请参见问题 1。(另外,如果您正在演示者层中使用 ViewModel - 好主意 - 您也需要在演示者层中使用 POCO 映射)。

【讨论】:

  • 我建议将 POCO 发送给客户,除非有技术要求您这样做(RIA 服务显然会这样做,但我需要确认)。所以你会暴露一个最干净的服务层
  • 非常感谢。如果我决定将 EF 更改为其他 ORM,我也应该修改服务层,对吧?
  • 没错。业务和服务层。因此,您不必担心将 DTO 填充和处理到解决方案的前沿,即服务层。
  • 谢谢,但为什么我不能在业务层上转换为 DTO?我会错架构吗?它只允许更改业务层。
  • 我更新了我的答案,即在性能超载成本方面灵活,作为简单性的权衡。并且更专注于您的问题。
【解决方案2】:

您可以让 POCO 实体手写并与持久层完全分离。 SDReys 是对的,使用生成的 EF 实体因为你的模型很臭。

这是一个简单 POCO 模型的粗略布局以及支持它的上下文。

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;}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    • 2012-03-04
    • 2011-08-12
    • 1970-01-01
    • 2010-12-25
    • 2012-09-02
    • 2013-12-06
    相关资源
    最近更新 更多