实体框架中导航属性的问题

时间:2011-03-31 13:30:39

标签: c# linq entity-framework linq-to-entities

当我执行此查询时,我可以在TypeP属性中导航:

var items = from item in context.ProductosBodegas.Include("Product.TypeP")
            select item;

但是当我执行此查询时,TypeP属性为null

var items = from item in context.ProductosBodegas.Include("Product.TypeP")
            select item.Product;

为什么会这样?

3 个答案:

答案 0 :(得分:4)

看起来Include仅影响直接返回的对象:

http://msdn.microsoft.com/en-us/library/bb896272.aspx

否则你可以打电话

item.TypePReference.Load()

但如果在循环中使用,这可能(并且会)导致性能问题(N + 1选择)。

另一种选择是“反转”您的查询,假设Product和ProductosBodegas之间的关系是双向的:

var items = context.Products
    .Include("TypeP")
    .Where(p => p.ProductosBodegas.Any( /* include condition here if needed */ ))

答案 1 :(得分:2)

据我所知,实体框架会在您不想返回完整实体但只返回投影时忽略包含。例如,参见答案here。我不确定这对所有类型的预测是否仍然有效,但显然它在您的情况下仍然有效。

您可以通过将要加载的导航属性添加到匿名类型来解决此问题:

var items = from item in context.ProductosBodegas
            select new {
                Product = item.Product,
                TypeP = item.Product.TypeP
            };

(此处不再需要.Include。)执行此查询后(例如使用.ToList()),您可以只投影到您想要的匿名类型的部分,例如这样:

var products = items.ToList().Select(x => x.Product);

products集合中的元素现在已加载TypeP引用属性。

修改

重要提示:请勿更改.ToList.Select...的顺序。虽然这......

var products = items.Select(x => x.Product).ToList();

...在语法上也是正确的,并且还返回产品的枚举,在这种情况下不会加载TypeP引用。必须首先在数据库中执行匿名类型的查询,并将anoynmous类型集合加载到内存中。然后你可以通过.Select方法丢弃你不希望拥有的anoynmous类型的部分。

答案 2 :(得分:1)

您应首先加载产品

var items = from item in context.ProductosBodegas.Include("Product").Include("Product.TypeP")
            select item;