2011-08-04 56 views
3
LINQ的子查詢

我有以下的數據庫結構(簡體)改善與DefaultIfEmpty

商店

StoreId 
RateId 

產品

ProductId 
Name 

價格

RateId 
Name 
IsDefault 

價格

PriceId 
ProductID 
RateId 
UnitPrice 

我有一個產品可以有多個價格取決於率表。我有多個商店,每個商店都有一個默認利率(rateId)。如果在給定費率的價格表中找不到產品的價格(rateId),則返回默認rateId和Product的價格。

現在UI代碼:

public ActionResult All() { 

     // Retrieve all products from database 
     var products = db.GetAllStoreProducts(StoreSettings.Default.StoreId) 
      .OrderBy(p => p.DateCreated); 

     var viewModel = new StoreBrowseViewModel() { 
      Name = "Todos los Productos", 
      Description = "Todos los Productos que forman parte de nuestro catálogo", 
      StoreProducts = products.ToList() 
     }; 

     return View("Browse1", viewModel); 
    } 

LINQ的代碼:

public IQueryable<Product> GetProducts() { 

     return storeDB.Products 
      .Include("Price"); 
    } 

    public IQueryable<StoreProduct> GetAllStoreProducts(Guid storeId) { 

     var store = storeDB.Stores 
      .SingleOrDefault(s => s.StoreId == storeId); 

     var products = GetProducts() 
       .Where(p => p.Visible) 
       .OrderBy(p => p.Name) 
       .Select(p => new StoreProduct() { 
        Family = p.Family, 
        Category = p.Category, 
        MetricType = p.MetricType, 
        Name = p.Name, 
        PublicArtUrl = p.ProductArtUrl, 
        DateCreated = p.DateCreated, 
        DateUpdated = p.DateModified, 
        UnitPrice = p.Prices 
         .Where(pc => pc.Rate.RateId == store.RateId) 
         .Select(b => b.UnitPrice) 
         .DefaultIfEmpty(p.Prices.FirstOrDefault(p2 => p2.Rate.IsDefault).UnitPrice) 
         .FirstOrDefault() 
       }); 

     return products; 
    } 

代碼工作正常,我得到了正確的價格給定存儲或默認價格,如果不'重寫'被發現,但...任何想法來提高linq查詢的性能? (不想使用sproc)

+0

如果覺得性能比較差,然後運行SQL事件探查器和檢查什麼是上述LINQ查詢生成的SQL查詢 – Ankur

+0

其實這不是窮人,但在LINQ表達式可以得到改善或變得更優雅 – Marc

回答

1
  • 您正在執行2個查詢,它們可以合併爲一個查詢。
  • 您只爲RateId屬性選擇整個商店實體。

另外: 我們使用以下規則來創建非常高性能的LINQ查詢:

  • Use compiled queries 它大大加快了查詢性能。它提供查詢的編譯和緩存以供重用。查詢編譯一次之後,您的程序就可以用其他參數執行它。
  • 選擇PresentationModels而不是實體。實體比表示實體的簡單類要重得多。
  • 切勿使用「包含」。這是一個真正的表演豬。只需創建一個可以一次獲取所有信息的查詢。