【问题标题】:Populate navigation properties when used in method passed to Where clause在传递给 Where 子句的方法中使用时填充导航属性
【发布时间】:2019-03-07 23:49:32
【问题描述】:

我有一个端点,它应该列出按搜索词过滤的所有候选人,所以我要做的是创建一个接受候选人实体和 searchTerm 作为参数的方法。然后我将该方法传递给 Where 子句,但问题是我得到了NullReferenceException,因为导航属性是空值。如果我将语句放在 Where 子句而不是方法中,那么它不会 throw Exception。问题是如何解决这个问题,但我想保留外部方法,因为会有更多逻辑,但我需要访问所有 navigation properties,即它们应该被填充。

if (!string.IsNullOrEmpty(searchTerm))
{
    query = query.Where(c => FilterBySearchTerm(c, searchTerm));
}

var result = await query.Select(c => new CandidaturesResponseModel()
{
    Id = c.Id,
    Name = c.PrimaryMember.FullName, // that's filled
}).ToListAsync();

private bool FilterBySearchTerm(Candidature c, string searchTerm)
{
    return c.PrimaryMember.FirstName.Contains(searchTerm); // here is the exception because PrimaryMember navigation property is null. So I want this to be filled.
}

【问题讨论】:

    标签: c# asp.net-core entity-framework-core asp.net-core-webapi


    【解决方案1】:

    问题是您正在使用 FilterBySearchTerm 方法实现查询。 EF 无法将随机方法转换为 SQL,因此它必须继续运行查询,取回结果,然后应用您的 Where。 EF 实际上会在过去抛出异常,但 EF Core 会静默处理。

    无论如何,一旦运行查询,您就完成了。您的过滤发生在内存中,此时,如果没有Include,您的相关实体将无法使用。总而言之,您需要在适当的位置构建过滤器(而不是使用单独的方法),以便 EF 能够将其转换为 SQL。

    另一种可能更好地为您服务的方法是将可查询对象传递给您的FilterBySearchTerm 方法。例如,不要这样做:

    query = query.Where(c => FilterBySearchTerm(c, searchTerm));
    

    query = FilterBySearchTerm(query, searchTerm);
    

    然后,在FilterBySearchTerm 中,您可以直接将Where 子句应用于传入的查询。这使您可以构建 EF 可以理解的实际查询,同时还可以封装逻辑。

    【讨论】:

    • 是的,我也是这么想的,但是 Where 返回 IQueryable 所以这应该意味着它还没有实现,当将 select linq 链接到查询时仍然可以访问导航属性,并且只有在链接 ToList 之后才会实现。我在第一篇文章中更新了代码,所以再检查一次。您的示例也可以完成工作,但我很好奇为什么会发生这种情况。
    • “哪里返回 IQueryable 所以这应该意味着它还没有实现” - 这不是真的。 IQueryable 是一个 LINQ 的东西。它是一种LINQ 可查询 的结构。与是否进行了数据库查询无关。
    • 我也找到了一个解决方案,如果那些随机方法返回表达式而不是布尔值,那么它就可以工作。
    【解决方案2】:

    只需使用Include方法添加PrimaryMember

      query = query.Include(x=> x.PrimaryMember).Where(c => FilterBySearchTerm(c, searchTerm));
    

    【讨论】:

    • 是的,但如果我不需要 PrimaryMembers 的所有属性,那不是很酷的解决方案。我很确定还有什么更好的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多