将 POCO 实体转换为业务实体
我愿意将实体框架集成为我的数据层。
我遵循文章并使用本教程生成了 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 的转换放在哪里?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
恕我直言,这太复杂了。为什么要使用 POCO 实体来实现持久性,并使用单独的对象来处理加载到 POCO 实体中的数据?听起来您的应用程序架构过度了。
ORM 的意思是对象关系映射。它意味着关系世界和对象世界之间的映射。通常它也可以翻译为数据库和业务对象之间的映射。因此,您应该使用 POCO 对象作为业务对象。这就是使用 POCO 的全部意义。如果您不想将它们用作业务对象,则不需要它们,可以直接使用默认实体对象。
如果您想使用 POCO 作为业务对象,只需让 EF 为您生成这些 POCO 并将部分类添加到定义您的方法的每个 POCO 中即可。
顺便提一句。您的业务对象实际上看起来像活动记录模式的实现。如果您想使用此模式,也许您应该检查 Windsor Active Record ,它基于NHibernate 之上。
编辑:
好吧。您可以使用您的类而不是生成的 POCO 实体。
一种方法是放弃 EFv4 和 EDMX 并检查新的 EFv4.1 及其新的流畅 API(也称为代码优先)用于映射。这对于单独的问题来说是完整的,或者只是在此处使用搜索。
您也可以使用 EDMX 来做到这一点。为了使这项工作顺利进行,您必须遵循一些基本规则,因为这整个过程是通过命名约定完成的。因为您已经有了类,所以必须在 EDMX 文件中修改它,以便概念模型与您的业务对象相同:
EDMX 包含三层:
这些是基本规则,但由于您已经有了业务对象,您很可能会发现难以映射它的情况。最好的方法就是询问具体问题。它很可能与一些复杂的属性、导航属性或继承有关。
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:
EDMX consists of three layers:
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.
如果我理解正确的话,这里有几种可能性。
您拥有表示数据库中的表的 POCO 实体,并且您有一些业务类,甚至可能是视图模型,并且您希望从一个模型移动到另一个模型。
第一种可能性是,在您的业务实体中,创建一个将 POCO 实体作为参数的构造函数,然后设置每个属性。
例如,
另一种选择是使用像 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.
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 aSalesDb.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.如果您使用 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.