我很困惑。代理对象的重点似乎是通过使用延迟加载和更好的更改跟踪来提高性能。但似乎当你从Linq到EF查询中检索代理结果,并希望通过HTTP将结果作为JSON返回时,由于序列化会导致错误,因为类型不匹配。
所有解决方案都说要关闭代理。那么如果你不能使用它们有什么意义呢?我缺少什么,如何在不实例化新的非代理匿名类型或POCO类型(对象分配)的情况下返回序列化代理对象,以镜像我正在返回的每个对象?
答案 0 :(得分:0)
使用延迟加载/代理的性能提升是您不会同时获取所有数据,从而更快地往返数据库并降低减慢甚至阻止其他数据库操作的可能性。如果你知道你将要加载所有数据,那么它不一定是性能改进。
话虽如此,如果您不能使用Include(...)(由于其局限性,例如GroupBy),有一些选项。
要加载多次访问数据库的数据,可以在引用或集合属性上使用Load方法显式加载数据而不访问它。然后,您可以禁用代理生成。 (http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx)
例如:
context.Entry( entityObj ).Reference( "PropertyName" ).Load();
context.Entry( entityObj ).Collection( "PropertyName" ).Load();
如果要对某些属性使用延迟加载w / proxies但希望避免WCF数据协定序列化在处理上下文后尝试延迟加载其他属性,则可以在离开DB上下文的范围之前分离实体。
EntityA a = null;
EntityA a2 = null;
using (var db = new TestEntities())
{
a = db.EntityAs.Where( ea => ea.Id == 1 ).Single();
db.Entry(a).State = System.Data.EntityState.Detached;
a2 = db.EntityAs.Where( ea => ea.Id == 2 ).Single();
}
var b1 = a.EntityB; // c will remain null; no exception thown
var b2 = a2.EntityB; // blows up b/c it attempts to lazy load