2016-02-12 83 views
5

我有一个非常奇怪的问题:ToList()扩展方法未能将结果转换为列表。这里是我的代码,标准的样板LINQ查询,我转换ToList()两次很好的措施Linq ToList()无法触发立即执行

var assets = new List<Asset>(); 

using (var ctx = new LeaseContext()) 
{ 
    assets = ctx.Assets.OrderBy(o => o.Reference).Where(w => w.Status == AssetStatus.Active).ToList(); 

    assets.ToList(); 
} 

return assets; 

但资产仍是System.Data.Entities.DynamicProxies列表....

我从来没有过这个问题。

+0

为什么你使用ToList()作为同一个变量? –

+0

由于不使用ToList()的结果,所以第二个'ToList()'什么也不做。 –

+0

我知道第二个ToList()是多余的,我只是想测试。 – franklores

回答

8

原因是延迟加载。在EF中启用延迟加载时(默认情况下),然后(再次,默认情况下)EF为每个实体创建动态代理。这是加载相关实体所必需的。动态代理将从实体类继承。所以在你的情况下,它将从Asset继承。但动态代理将参考创建其实例的上下文。它将覆盖导航属性(这是虚拟的),通过存储在动态代理中的上下文来查询实体。

将派生类型的实例添加到基本类型列表是完全合法的。

如果你不想使用动态代理,那么就禁用延迟加载和代理的创建:

ctx.Configuration.LazyLoadingEnabled = false; // turn-off loading on-demand 
ctx.Configuration.ProxyCreationEnabled = false; // turn-off wrapper class generation 

技术上你可以关闭代理生成和延迟加载将无法正常工作。但我更愿意明确关闭这两个设置。

+0

我已添加该声明,但仍无效。 使用(VAR CTX =新LeaseContext()) \t \t \t { \t \t \t \t ctx.Configuration.LazyLoadingEnabled = FALSE; (=> w.Status == AssetStatus.Active).Select(x => x).ToList();其中, \t \t \t} \t \t \t \t \t \t收益资产; – franklores

+0

@franklores在使用'cxt'查询资产之前,您应该添加此语句 –

+0

@franklores抱歉,我忘记了第二个配置设置 - 有一个用于禁用代理创建的单独配置 –