簡體   English   中英

如何在Linq中避免“選擇n + 1”模式

[英]How to avoid “select n+1” pattern in Linq

我有以下形式的查詢(包括LinqKit):

Expression<Func<Country, DateTime, bool>> countryIndepBeforeExpr = 
  (ct, dt) => ct.IndependenceDate <= dt;
DateTime someDate = GetSomeDate();
var q = db.Continent.AsExpandable().Select(c =>
  new 
  {
    c.ID,
    c.Name,
    c.Area,
    Countries = c.Countries.AsQueryable()
                 .Where(ct => countryIndepBeforeExpr.Invoke(ct, someDate))
                 .Select(ct => new {ct.ID, ct.Name, ct.IndependenceDate})
  });

現在我想通過迭代q ...但由於Countries的每個元素的屬性的類型的IQueryable ,這將是懶加載,導致被執行N + 1個查詢,這是不是很好。

編寫此查詢以便所有必要的數據將在單個查詢中提取到db的正確方法是什么?

編輯

嗯,如果我在問這個問題之前實際運行了Sql跟蹤,那可能會有所幫助。 以為 ,因為內財產是類型的IQueryable ,這將是懶加載...但是做了一些實際測試后,事實證明,LINQ到實體是足夠聰明的同時運行整個查詢。

很抱歉浪費您的全部時間。 我將刪除該問題,但是由於它已經有了答案,所以不能。 也許可以作為對他人的某種警告,在假設它成立之前對您的假設進行檢驗

呼叫大洲時,將國家/地區包括在模型中。 用這樣的東西:

var continents = db.Continent.Include(c => c.Countries).ToArray();

然后,您可以在沒有iQueryable對象的情況下進行linq操作。

認為這應該工作(將AsExpandable()移到IQueryable根目錄):

var q = db.Continent
          .AsExpandable()
          .Select(c => new 
          {
              c.ID,
              c.Name,
              c.Area,
              Countries = c.Countries
                  .Where(ct => countryIndepBeforeExpr.Invoke(ct, someDate))
                  .Select(ct => new {ct.ID, ct.Name, ct.IndependenceDate})
});

如果沒有,請創建兩個IQueryable並將它們連接在一起:

var continents = db.Continents;
var countries = db.Countries
                  .AsExpandable()
                  .Where(c => countryIndepBeforeExpr.Invoke(c, someDate))
                  .Select(c => new { c.ID, c.Name, c.IndependenceDate });

var q = continents.GroupJoin(countries,
    continent => continent.ID,
    country => country.ContinentId,
    (continent, countries) => new
    {
        continent.ID,
        continent.Name,
        continent.Area,
        Countries = countries.Select(c => new
        {
            c.ID,
            c.Name,
            c.IndependenceDate
        })
    });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM