【问题标题】:Why doesn't Include have any effect?为什么 Include 没有任何效果?
【发布时间】:2026-02-20 19:20:06
【问题描述】:

我正在执行以下 LINQ 查询,该查询有效但不返回已填充的导航属性 Person,我得到 null

public IEnumerable<SharePeople> GetSharePeopeByCarId(int carId)
{
    return from q in _context.Cars
           join s in _context.Shares 
               on q.CarId equals s.Car.CarId
           join p in _context.SharePeople.Include(p => p.Person) 
               on s.ShareId equals p.ShareId
           where q.CarId == carId
           select p;
}

我不知道为什么,因为当我使用像 _context.SharePeople.Include(p =&gt; p.Person) 这样的常规扩展方法时,它可以工作。

【问题讨论】:

  • 您确定您符合条件s.ShareId equals p.ShareId 吗?
  • 是的,因为我得到了一条记录,但Personproperty 为空,所有其他值都可以。
  • 我在SharePeople 中有一个Personproperty。
  • 有你的上下文Configuration.LazyLoadingEnabled = false

标签: c# linq entity-framework extension-methods


【解决方案1】:

This post 清楚地描述了Include 何时有效和无效。

关键部分是查询的形状,即选定的列。如果在Include 之后有任何改变形状,Include 将不再起作用。

在您的查询中,形状发生了四次变化,在这些语句部分中:

  1. from q in _context.Cars:查询将只返回 Car
  2. join s in _context.Shares: Car + Share
  3. join p in _context.SharePeople: Car + Share + SharePeople 列。 这是包含
  4. select p,仅SharePeople

一旦意识到这一点,补救措施就很简单了:

(from q ... select p).Include(p => p.Person)

这也适用于查询的形状看似没有改变,但查询会产生投影的情况。假设你有select new { q, s, p }。这仍然会选择Car + Share + SharePeople 列,与Include 之前相同。但是,查询会生成匿名类型。这种类型本身没有任何可以由Include 填充的导航属性,因此Include 没有做任何事情。这是by design

【讨论】:

  • 加一。这个答案很好,向我澄清了很多事情。非常感谢
【解决方案2】:

使用 ste-fu 方法不起作用,但通过它的变体,我能够将其投入使用。

我猜 Gert Arnold 回答了为什么它不起作用,但既然我在这里工作了,那就是代码:

var sharePeople = Context.SharePeople.Include("Person");

return sharePeople.Where(s =&gt; s.Shares.Car.CarId == carId);

【讨论】: