什么应该在EF4中使用POCO?

时间:2010-06-22 17:25:07

标签: entity-framework oop entity-framework-4 poco

我们有一个ASP.Net MVC2网站,并且正在利用EF4进行数据库访问等。作为EF4的新手,我们遇到了EF4 POCO概念,但是并没有完全理解它。

一般来说,我听说过POCO被定义为“不依赖于外部框架”的对象。在EF4的情况下,我猜这意味着POCO意味着以某种方式创建更轻量级的实体?如果是这种情况,POCO没有什么样的EF4管道,这有什么优点/缺点,POCO需要多少额外的开发工作。总之,何时在EF4中使用POCO是好的?

2 个答案:

答案 0 :(得分:14)

“POCO”在ORM领域是一个模糊的术语。人们不同地使用它来表示:

  • “Pure”POCO,不会改变跟踪,延迟加载,具有私有属性等。它们可能难以使用。
  • Psuedo-POCO代理:包含所有public virtual并且在运行时具有不同类型的类型。
  • 自我跟踪实体。不是POCO,而是EntityObject

我发现“不依赖于外部框架”的定义有些自私。这是忽略框架限制的一种方式。即,代理在我的书中不是真正的POCO,但它们符合这个定义。

EntityObject出了什么问题?不是很多。它相当轻量级,它是.NET的一部分。它甚至在.NET 4客户端配置文件中。它甚至没有把你链接到EF。虽然将它用作具有不同框架的“POCO类型”会有点奇怪,但它可以正常工作。但是,它不是在Silverlight中,IIRC。

POCO实体更难以使用,因为您丢失了EntityObject免费提供的内容。这不是很多,但在选择POCO之前需要考虑的因为“它们很酷”,特别是那些刚接触EF的人。

许多对POCO抱有虔诚信息的人倾向于忽略这一点:映射非POCO类型绝不会限制您在外部暴露这些非POCO类型。您的数据服务可以将映射的非POCO类型投影到未映射的POCO DTO上,您可以选择仅公开这些类型,即:

public IEnumerable<FooDto> IFooRepository.SelectAll()
{
    return from f in Context.Foos
           select new FooDto { Id = f.Id, Name = f.Name };
}

因此,如果您愿意,映射类型和数据服务类型可能很容易成为不同的问题。

什么时候你绝对需要非EntityObject类型的映射?好吧,如果你需要自我跟踪实体,那么这就是一个开放和关闭的案例。如果必须将映射的类型公开给Silverlight,那么也应该清楚。

除此之外,它还不太清楚。如果您正在编写一个供公众使用的数据服务,那么您不应该将DTO设为EntityObject个子类型,因为这会妨碍以后插入不同的框架。 我永远不会创建一个依赖于任何一个框架的不可变的公共接口,甚至包含在.NET中。另一方面,正如我上面所说,你可以暴露一种类型并映射另一种类型;不需要公开映射类型,并且通常很好的理由不公开它们(可能它们包含非公共数据)。

答案 1 :(得分:9)

我完全赞同克雷格,POCO更难以合作。

我将添加更多关于POCO的目的,我希望您能理解何时应该使用以及何时不使用它。

模型和服务是核心

模型和服务是您应用程序中最重要的部分之一,它是一个NO-NO-NO改变,您无法避免将模型和服务与应用程序的任何部分紧密耦合,因此模型的小变化需要更改整个应用程序。

关于灵活性

POCO是一个特定于语言的问题,而不是特定于框架的问题。它是一个简单的类,没有依赖于框架特定的类,你可以在所有.net版本中使用POCO,包括微框架和紧凑框架。

关于测试

POCO非常容易进行单元测试,因为它不依赖于非单元测试友好类。

关于改变

升级/降级,在MONO这样的不同环境中制作新的客户端应用程序?没问题,您可以继续使用您的服务和型号,即使是最差的升级/降级也只会出现在View and Service Cotext Helper上。

这很自然

创建和使用POCO既简单又自然,您可以清楚地编写业务流程。

但请记住,POCO对框架不友好

我同意Craig,POCO TOO COOL ,Too Cool与新朋友交朋友。看看WPF它需要一个实现INotifyPropertyChanged的模型,你要做什么来实现呢?您可以制作包装器,也可以对模型进行动态代理。但这需要更先进的技术和代码来维护。