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

发布于 2024-10-28 03:30:54 字数 382 浏览 1 评论 0原文

当我执行此查询时,我可以在 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;

这是为什么?

When I execute this query I can navigate in TypeP property:

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

But when I execute this query the TypeP Property is null:

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

Why is this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

笑咖 2024-11-04 03:30:55

据我所知,只要您不想返回完整实体而只想返回投影,实体框架就会忽略包含。例如,请参阅答案 此处。我不确定这是否仍然适用于所有类型的预测,但显然它在您的情况下仍然有效。

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

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

此处不再需要 .Ininclude。)执行此查询后(通过使用 .ToList () 例如)您可以仅投影到您想要拥有的匿名类型的部分,如下所示:

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

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

编辑:

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

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

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

As far as I know Entity Framework ignores Includes as soon as you don't want to return full entities but only projections. See for instance the answer here. I am not sure if that is still valid for all types of projections but apparently it is still valid in your situation.

You can workaround this by adding the navigation property you want to have loaded into an anonymous type:

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

(You don't need .Include here anymore.) After executing this query (by using .ToList() for instance) you can project to only the part of the anonymous type you want to have, like so:

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

The elements in this products collection have loaded the TypeP reference property now.

Edit:

Important note: Don't change the order of .ToList and .Select.... While this ...

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

... is also syntactically correct and also returns an enumeration of products, the TypeP reference will NOT be loaded in this case. The query for the anonymous type must be executed at first in the database and the anoynmous type collection loaded into memory. Then you can throw away the part of the anoynmous type you don't want to have by the .Select method.

雨的味道风的声音 2024-11-04 03:30:55

你应该先加载产品

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

you should load product first

var items = from item in context.ProductosBodegas.Include("Product").Include("Product.TypeP")
            select item;
像极了他 2024-11-04 03:30:54

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

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

否则你可以调用

item.TypePReference.Load()

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

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

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

Looks like Include only affects the directly returned object :

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

Otherwise you can call

item.TypePReference.Load()

But this can (and will) lead to perfornance issues (N+1 select), if used in a loop.

Another option would be to "reverse" your query, assuming relationship between Product and ProductosBodegas is bidirectional :

var items = context.Products
    .Include("TypeP")
    .Where(p => p.ProductosBodegas.Any( /* include condition here if needed */ ))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文