IQueryable< T& gt; .include()被忽略 [英] IQueryable<T>.Include() gets ignored

查看:48
本文介绍了IQueryable< T& gt; .include()被忽略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有彼此关联的 Parent Child 实体,从1到M.我需要在单个SQL查询中与子代一起查询子代,但是 Include 方法在某些情况下无法正常工作.
此查询对 Parent Child 表(通过JOIN)进行了正确的单个查询:

I have Parent and Child entities related to each other as 1 to M. I need to query childs together with parents within a single SQL query, but the Include method is not properly working for some cases.
This one makes a correct single query for both Parent and Child tables (via JOIN):

var r1 =
    ctx.Set<Parent>()
       .Include(p => p.Childs)
       .Where(p => p.Id == 1)
       .ToList();

一旦我动态创建了一个匿名对象,孩子们就会迷路,而SQL只包含Parent的字段.检索孩子仍然很懒-他们仍未加载:

Once i create an anonymous object on the fly, children are getting lost and SQL contains only Parent's fields. Retrieval of children remains lazy - they are still not loaded:

var r2 =
    ctx.Set<Parent>()
       .Include(p => p.Childs)
       .Where(p => p.Id == 2)
       .Select(p => new { myParent = p})
       .ToList();

问题:

  1. 为什么会这样?
  2. 如何在LINQ中构造一个新的匿名对象,以使孩子不会迷路?

p.s.我想保持Parent的Childs属性为虚拟.

p.s. i'd like keep Childs property of Parent virtual.

推荐答案

这是我所知道的所有EF版本中的普遍问题.EF尝试尽可能地传递包含",但是当查询的形状发生变化"时,包含"将不可逆转地丢失.

This is a general problem in all versions of EF known to me. EF tries hard to pass the 'includes' as far as possible, but when "the shape of the query changes", the 'includes' are irreversibly lost.

查询的形状"例如在以下情况下发生更改:

The "shape" of the query changes for example, when:

  • 使用投影(不是选择整个对象而是仅选择某些字段或其他对象)
  • 使用了分组依据或其他聚合方式
  • ..,也许还有更多情况,目前我不记得了.

可悲的是,我也不记得在MSDN上我偶然发现了查询形状"的解释.如果找到它,我将在此处放置一个链接.

Sadly, I also dont remember where on MSDN I stumbled upon the "shape of the query" explanation. If I find it, I'll drop here a link.

该解决方案实际上非常简单:只需尽早指定"include"部分,但最终结果即可.因此,不要在开始时使用 set.include(x),而是使用 .Select(.. => new {..,x})包含"x"手动.在分组过程中也可以使用,因为您也可以在那里进行投影.

The solution is actually quite simple: simply specify the 'include' part not early, but at the final result. So, instead of set.include(x) at beginning, do .Select( .. => new { .., x }) to include the 'x' manually. It also works during grouping, as you can do a projection there too.

但是,这不是解决方案.这是手动修补程序/修补程序,不能解决任何问题.考虑到您可能希望通过某些接口公开"IQueryable<>",因此您可能希望公开具有一些已包括在内的基本查询".当然,以一般方式不可能这样做,就像界面的客户端进行投影或分组一样,他将丢失包含内容,甚至不知道应该包含哪些内容.是.对我来说,这是EF的主要缺陷.

However, this is not a solution. This is a manual patch/hotfix, which does not solve anything. Considering that you might want to expose a "IQueryable<>" through some interface, you may like to expose a "base query" with some things already .Included. And of course, this is simply not possible to do in a general way, as if the client of the interface does a projection or grouping, he will lose the includes and he will not even know which ones should be. For me, this is a major deficiency in EF.

刚刚找到一个:.包含在以下查询中不会确实包括 .

just found one: .Include in following query does not include really Not MSDN, but just as good.

这篇关于IQueryable&lt; T&amp; gt; .include()被忽略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆