【问题标题】:converting POCO entity to business entity将 POCO 实体转换为业务实体
【发布时间】:2011-08-06 23:38:47
【问题描述】:

我愿意将实体框架集成为我的数据层。

我使用本教程关注文章并生成 poco 实体:http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the-entity-framework.aspx

我有自己的业务对象。这是我的业务对象 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...
    }
}

我不知道如何将 POCO 实体转换为我的业务实体。
从 POCO 到 POCO 的转换应该放在哪里?

【问题讨论】:

    标签: .net entity-framework entity-framework-4 poco business-objects


    【解决方案1】:

    如果我没听错的话,这里有几个可能性。

    您有代表数据库中表的 POCO 实体,并且您有一些业务类,甚至可能是视图模型,并且您想从一个移动到另一个。

    第一种可能性,在您的业务实体中,创建一个将您的 POCO 实体作为参数的构造函数,然后设置每个属性。

    例如

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

    另一种选择是使用像AutoMapper这样的工具

    它将帮助您自动映射(因此得名;))这两个实体。

    我可能建议的一件事是不要放置 Branch.GetListOfBranches(),而是想出一个像 DataLayer.cs 之类的类,将尽可能多的查询逻辑放在那里。这样一来,您就不会让单个对象知道您的数据上下文,并且当您需要进行更改时,可以进行更改的地方就更少了。

    我们有一个名为 Sales 的数据库,我们的类称为 SalesDb。然后我们使用该类来检索我们需要的实体。所以我们可能会使用SalesDb.GetLeads(),甚至是SalesDb.GetLeads(Filter f) 来过滤掉我们不需要的东西。现在,SalesDb 正在控制上下文,我的 Leads 类不需要知道任何有关它的信息。

    【讨论】:

    • 您的 SalesDb 类实际上是存储库类吗?
    • 或多或少,是的。我们编写了一堆通用方法,因此我们可以在存储库中进行过滤和排序。我们有 Filter 其中 T 可以是我们的任何数据库模型(我们通过接口定义它)
    【解决方案2】:

    恕我直言,这太复杂了。为什么你有用于持久性的 POCO 实体和用于处理加载到 POCO 实体中的数据的单独对象?听起来您的应用程序架构过度了。

    ORM 表示对象关系映射。这意味着关系世界和对象世界之间的映射。通常它也可以翻译为数据库和您的业务对象之间的映射。所以你应该使用你的 POCO 对象作为你的业务对象。这就是使用 POCO 的全部意义。如果您不想将它们用作业务对象,则不需要它们,您可以直接使用默认实体对象。

    如果您想将 POCO 用作业务对象,只需让 EF 为您生成这些 POCO,并将部分类添加到定义您的方法的每个 POCO。

    顺便说一句。您的业​​务对象实际上看起来像 Active Record pattern 的实现。如果你想使用这种模式,也许你应该检查基于 NHibernate 之上的Windsor Active Record。

    编辑:

    嗯。您可以使用您的类而不是生成的 POCO 实体。

    一种方法是放弃 EFv4 和 EDMX 并检查新的 EFv4.1 and its new fluent API(又名代码优先)进行映射。这对于单独的问题来说是完整的,或者只是在 SO 上使用搜索。

    您也可以使用 EDMX 做到这一点。您必须遵循一些基本规则才能完成这项工作,因为这一切都是通过命名约定完成的。因为您已经有了类,所以您必须在 EDMX 文件中修改它,以便概念模型与您的业务对象相同:

    • 必须保存或加载的每个业务对象都必须在概念模型中具有实体
    • 实体必须与业务对象同名。您还必须在属性窗口中正确设置实体(摘要、访问级别和基本实体必须与您的业务对象中的相同)
    • 业务对象中的每个存储属性都必须在概念模型中的实体中具有一个属性。同样,您必须正确设置每个属性(getter 和 setter 可访问性、类型、可为空等)。

    EDMX 由三层组成:

    • SSDL - 数据库的描述。这几乎总是生成的,您不能直接在设计器中修改它。
    • CSDL - 实体的描述必须与您的业务对象相同。这是您在设计器中修改的内容。您可以根据需要重命名字段。
    • MSL - SSDL 和 CSDL 之间的映射。如果您在设计器中的任何实体上打开上下文菜单,您将看到表映射。它将打开一个窗口,其中定义了 CSDL 和 SSDL 之间的映射。

    这些是基本规则,但由于您已经拥有业务对象,您很可能会发现难以映射它的情况。最好的方法是简单地询问这个具体问题。很可能是一些复杂的属性、导航属性或继承。

    【讨论】:

    • +1 我同意。我认为没有必要将它们分开。当您开始加载关系等时,它也会给您带来一些严重的痛苦,您最终会构建自己的延迟加载等,这是 or/m 的主要功能之一。
    • @Ladislav Mrnka:我已经有了自己的商业实体。我所有的应用程序都是使用它们编写的。所以我不能使用 POCO 对象作为我的业务对象。另一方面,我的业务对象具有继承性,它们是复杂的对象 - 与 POCO 不同。我不确定我是否可以使用它们来代替 POCO。我真的会举一个例子。
    • @Naor:我编辑了我的答案。这是一个很大的例子。您必须展示具体的问题,即您不知道如何将其映射以获取样本的具体问题。
    • @Ladislav Mrnka:感谢您的回答。您能以我下一个问题 (stackoverflow.com/questions/5690208/…) 中的示例为例吗?
    • @Ladislav Mrnka:我已经阅读了您的答案两次,但仍然不明白。如何将数据库映射到我的对象?在 edmx 中更改成员仍会将字段映射到新成员名称?
    【解决方案3】:

    如果您将 POCO 用作外部数据合同, 你可能想要你的模型给你不同的实体/类 为了防止之间的松散耦合 您的外部合同以及您的应用程序如何工作。

    在检索数据合同时, 您可以从上下文中检索匹配的实体, 然后将数据合约中的值注入实体/实体, 使用诸如 ValueInjecter 之类的工具。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-14
      • 2012-09-24
      • 2019-04-22
      • 2019-05-01
      • 2012-03-22
      • 2012-09-13
      • 1970-01-01
      相关资源
      最近更新 更多