實體框架核心忽略.Include(..)而沒有.ToList(..)間接

.net-core asp.net-core c# entity-framework entity-framework-core

如所指出的從EF核心文檔中的“加載有關的數據” ,我們可以使用.Include(..)從熱切負載導航屬性DbSet (或通用IQueryable<T>鏈接回一個EF上下文)。

這意味著,給定以下模型:

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; }
}

..然後以下代碼應該工作:

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()

如果更改查詢以使其不再返回查詢開頭的實體類型的實例,則忽略包含運算符。 [snip]默認情況下,EF Core會在忽略include運算符時記錄警告。

我不確定如何在上面調用相關的.Any() 。是的,查詢沒有返回原始類型(當然它返回bool )但同時,也沒有記錄警告以告知它被忽略。

我的問題是:

  • 這是一個預計會起作用的用例嗎?我應該在EF Core中提出錯誤嗎?
  • 如果它沒有預期,解決方法如下(調用.ToList()但顯然會加載的一切,找出如果我們有一個東西.Any()這可以很容易地查詢(並會這樣在EF6)。什麼是解決方法來獲得這個.Any()在服務器端工作,因此不需要ToList將其放入內存?

解決方法:

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

完全可重複的樣本: https//gist.github.com/rudiv/3aa3e1bb65b86ec78ec6f5620ee236ab

熱門答案

行為是預期的,但您可以使用顯式加載來進行更有效的查詢,如下所示。

2個單獨的查詢,但不需要加載所有TestEntityB

// First query
var testEntityAs = context.TestEntityAs.ToList();
var testEntityAsIds = testEntityAs.Select(t => t.Id);

// Second query, can apply filter of Hello World without loading all TestEntityBs
context.TestEntityBs
    .Where(t => testEntityAsIds.Contains(t.Id) && t.Property == "Hello World")
    .Load();

// In memory check
var isAny = testEntityAs.Any(t => !string.IsNullOrEmpty(t.BProperty));


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow