【问题标题】:Can't find single property and navigate related data without IQueryable all properties如果没有 IQueryable 所有属性,则无法找到单个属性并导航相关数据
【发布时间】:2021-09-18 12:33:54
【问题描述】:

我的对象有我想要访问的关系数据属性:

public class Person
{
   public ICollection<Address> Addresses { get; private set; } = new Collection<Address>();
   ...
}

public class Address
{
   ...
   public int PersonId { get; set; }
   public Person Person { get; set; }
   ...
}

我发现在没有延迟加载(以及拉入代理等)的情况下遍历甚至锻炼此导航属性的唯一方法是急切加载它:

var entityList = await _context.Persons.Where(p => p.Id == request.PersonId)
    .Include(p => p.Addresses)
    .ToListAsync();

这很不方便,因为现在我总是必须执行以下操作才能干净地访问类(及其属性):

var person = entityList.FirstOrDefault();

Microsoft docs 中的每个示例:

var blogs = context.Blogs
    .Include(blog => blog.Posts)
    .ToList();

在加载相关数据之前,它们会抓取每个博客实体,而不仅仅是一个实体。

我无法显式加载,因为这依赖于我无法通过注入的DbContext 接口访问的public virtual EntityEntry&lt;TEntity&gt; Entry&lt;TEntity&gt;(TEntity entity)

如果没有 IQuerable where 表达式,是否有更简洁的方法来执行此操作?我只是想找到我的单个实体并浏览它的属性。

【问题讨论】:

  • 你不能_context.Persons..Include(p =&gt; p.Addresses).ToListAsync();

标签: .net entity-framework linq entity-framework-core iqueryable


【解决方案1】:

根据您的问题,我认为您将急切/延迟加载与 LINQ 执行方法混淆了。对于这样的事情:

var entityList = await _context.Persons.Where(p => p.Id == request.PersonId)
    .Include(p => p.Addresses)
    .ToListAsync();
var person = entityList.FirstOrDefault();

你真的只想要 1 个人的地址,然后使用:

var person = await _context.Persons
    .Include(p => p.Addresses)
    .SingleOrDefaultAsync(p => p.Id == request.PersonId);
    

这将获取人员及其相关地址。如果您希望始终有记录,最好使用SingleAsync 而不是“OrDefault”变体。 (如果发送了无效的 PersonId,则抛出异常)

Include 确定预加载。 ToList 只是告诉 Linq 期待可能的多个匹配行。您可能遇到问题的地方是尝试在 DbSet 上使用 Find,它对 Addresses 集合采用延迟加载。

First 方法只能与 OrderBy 子句一起使用,在该子句中您期望可能有多个匹配行,以确保查询是可预测的。

【讨论】:

  • 哇——你搞定了。这不仅有效,而且您预测我误解了加载和 LINQ 执行方法是正确的。您还正确地猜测我一直在尝试使用 Find 并且无法解释为什么它不起作用,直到现在,我找不到像您这样的示例。太感谢了;我已经坚持了好几个小时了。
猜你喜欢
  • 2015-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-10
  • 2013-09-08
  • 2021-02-06
  • 1970-01-01
相关资源
最近更新 更多