将 POCO 实体转换为业务实体

发布于 2024-11-02 03:17:22 字数 1584 浏览 1 评论 0 原文

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

我遵循文章并使用本教程生成了 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 的转换放在哪里?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

长伴 2024-11-09 03:17:22

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

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

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

顺便提一句。您的业​​务对象实际上看起来像活动记录模式的实现。如果您想使用此模式,也许您应该检查 Windsor Active Record ,它基于NHibernate 之上。

编辑:

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

一种方法是放弃 EFv4 和 EDMX 并检查新的 EFv4.1 及其新的流畅 API(也称为代码优先)用于映射。这对于单独的问题来说是完整的,或者只是在此处使用搜索。

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

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

EDMX 包含三层:

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

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

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.

述情 2024-11-09 03:17:22

如果我理解正确的话,这里有几种可能性。

您拥有表示数据库中的表的 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 类不需要了解任何有关它的信息。

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.

冷情 2024-11-09 03:17:22

如果您使用 POCO 作为外部数据合约,
您可能希望您的模型适合不同的实体/类
为了防止之间的松耦合
您的外部合同以及您的应用程序如何工作。

在检索数据合同时,
您可以从上下文中检索匹配的实体,
然后将数据合约中的值注入到一个或多个实体中,
使用 ValueInjecter 等工具。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文