2011-08-04 28 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而不是实体。实体比表示实体的简单类要重得多。
  • 切勿使用“包含”。这是一个真正的表演猪。只需创建一个可以一次获取所有信息的查询。