实体框架核心忽略.include(..)而没有.ToList(..) [英] Entity Framework Core ignoring .Include(..) without .ToList(..) indirectly

查看:66
本文介绍了实体框架核心忽略.include(..)而没有.ToList(..)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如EF核心文档加载相关数据中 我们可以使用 .Include(..) DbSet (或通用)中快速加载导航属性 IQueryable< T> 链接回EF上下文)。

As noted in "Loading Related Data" from EF Core Documentation we can use .Include(..) to Eagerly Load navigation properties from the DbSet (or generic IQueryable<T> linking back to an EF context).

这意味着,鉴于以下模型:

This means that, given the following models:

public class TestEntityA
{
    public int Id { get; set; }
    public int TestEntityBId { get; set; }
    public TestEntityB TestEntityB { get; set; }

    public string BProperty { get { return TestEntityB.Property; } }
}

public class TestEntityB
{
    public int Id { get; set; }
    public string Property { get; set; }
}

..这样的代码应该起作用:

.. then code such as the following should work:

context.TestEntityAs
    .Include(m => m.TestEntityB)
    .Any(m => m.BProperty == "Hello World");
    /*
     * Note that the below DOES work by using the nav property directly
     * in the query, but that is not always going to be an option for
     * whatever reason. If it's .Included it should be available through
     * INNER JOINing it into the base query before the .Any runs.
     * .Any(m => m.TestEntityB.Property == "Hello World");
     */

但是不是。

我注意到有一个警告,如果查询不返回最初请求的类型,可以忽略 .Include()

I note that there is a caveat where .Include() could be ignored should a query not return the type that is initially requested:


如果更改查询以使其不再返回查询开始的实体类型的实例,那么将忽略include运算符。 [snip]默认情况下,当忽略包含运算符时,EF Core将记录警告。

If you change the query so that it no longer returns instances of the entity type that the query began with, then the include operators are ignored. [snip] By default, EF Core will log a warning when include operators are ignored.

我不确定在上面对 .Any()是相关的。是的,查询未返回原始类型(当然,它返回的是 bool ),但同时也未记录警告,以表明它已被忽略。

I'm not sure how, in the above call to .Any() that is relevant. Yes, the query is not returning the original type (it's returning a bool of course) but at the same time, the Warning is also not logged to advise that it is being ignored.

我的问题是:


  • 这是一个用例吗?期望工作?我应该在EF Core中引发一个错误吗?

  • 如果没有预期, a 解决方法如下(调用 .ToList() ),但这显然会加载所有内容,以查找 .Any()上是否有任何内容,这很容易成为查询(并且会在EF6中是这样)。要使此 .Any()在服务器端工作,而又不需要ToList放入内存,有什么解决方法?

  • Is this a usage case that is expected to work? Should I raise a bug in EF Core?
  • If it's not expected, a workaround is as below (to call .ToList()) but that would obviously load everything, to find out if we have anything on a .Any() which could easily be a query (and would be as such in EF6). What is a workaround to get this .Any() to work on the server side thus not requiring the ToList to put it in memory?

解决方法:

context.TestEntityAs
    .Include(m => m.TestEntityB)
    .ToList()
    .Any(m => m.BProperty == "Hello World");

完全可复制的示例: https://gist.github.com/rudiv/3aa3e1bb65b86ec78ec6f5620ee236ab

推荐答案

取决于数据,实现此目标的有效方法可能是加载单个记录:

Depending on the data, likely the efficient way to achieve that would be to load a single record:

context.TestEntityAs
    .Include(m => m.TestEntityB)
    .Where(m => m.BProperty == "Hello World")
    .FirstOrDefault() != null;

这篇关于实体框架核心忽略.include(..)而没有.ToList(..)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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