0

我很困扰。代理对象的重点似乎是通过使用延迟加载和更好的更改跟踪来提高性能。但是,当您从 Linq 到 EF 查询中检索代理结果并希望通过 HTTP 将该结果作为 JSON 返回时,由于存在类型不匹配,您将由于序列化而出错。

所有解决方案都说要关闭代理。那么,如果你不能使用它们,那么拥有它们有什么意义呢?我错过了什么,如何返回序列化的代理对象,而不实例化新的非代理匿名类型或 POCO 类型(对象分配)来镜像我返回的每个对象?

4

1 回答 1

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();

如果您想对某些属性使用带有代理的延迟加载,但希望避免 WCF 数据协定序列化在释放上下文后尝试延迟加载其他属性,您可以在离开数据库上下文的范围之前分离实体。

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
于 2013-03-26T22:21:08.987 回答