实体框架POCO序列化

时间:2012-01-12 10:59:32

标签: asp.net-mvc-3 serialization entity-framework-4.1 lazy-loading poco

我将很快开始编写新的Web应用程序。该应用程序将使用ASP.Net MVC 3和Entity Framework 4.1(Database First方法)构建。我将使用ADO.NET POCO实体生成器创建POCO类,而不是使用默认的EntityObject类。

当我使用此工具创建POCO时,它会自动将Virtual关键字添加到所有属性以进行更改跟踪和延迟加载的导航属性。

然而,我从演示中读到并看到,Julie Lerman(EF Guru!)似乎关闭了延迟加载并修改了她的POCO模板,以便从她的POCO类中删除Virtual关键字。 Julie说她之所以这样做是因为她正在为WCF服务编写应用程序,并且使用Virtual关键字会导致序列化问题。她说,当一个对象被序列化时,序列化程序会触摸导航属性,然后触发延迟加载,在你知道之前,你正在通过网络拉动整个数据库。

我认为当她说这可能会将整个数据库拉到网上时,朱莉可能会夸大其词,但即便如此,这个想法让我感到害怕!

我的问题是(最后),我是否应该从我的POCO类中为我的MVC应用程序删除Virtual关键字,并使用DectectChanges进行我的更改跟踪和Eager Loading来请求导航属性。

非常感谢您对此的帮助。

一如既往地感谢。

2 个答案:

答案 0 :(得分:4)

序列化确实可以触发延迟加载,因为导航属性的getter无法检测调用者是序列化程序还是用户代码。

这不是唯一的问题:您是否拥有虚拟导航属性或所有属性,因为虚拟EF将在运行时为您的实体创建代理类型,因此序列化程序在运行时必须处理的实体实例通常是类型与您定义的类型不同。

Julie的建议是解决问题的最简单,最合理的方法,但如果您仍希望在大多数情况下使用代理的功能,并且有时仅使用WCF对其进行序列化,则还有其他可用的解决方法:

  • 您可以使用DataContractResolver将要序列化的代理类型映射为原始类型
  • 您也可以仅在要序列化图表时关闭延迟加载

此博客文章中包含更多详细信息:http://blogs.msdn.com/b/adonet/archive/2010/01/05/poco-proxies-part-2-serializing-poco-proxies.aspx

除此之外,我的建议是你使用DbContext模板而不是POCO模板。 DbContext是我们作为EF 4.1的一部分发布的新API,旨在提高生产力。它有几个优点,例如它将自动执行DetectChanges,因此您通常不需要关心自己调用方法。我们为DbContext生成的POCO实体也比我们使用POCO模板生成的实体更简单。您应该能够使用DbContext找到许多MVC示例。

答案 1 :(得分:0)

这取决于你的需要,如果你要序列化你的POCO类而不是你应该删除它们(例如:当使用WCF服务或基本上任何会序列化整个对象的东西时)。但是,如果您只是构建一个需要访问您的类的Web应用程序,那么当您通过代码控制将在类中访问的对象时,我将它们保留在您的类中。