使用DefaultIfEmpty改进Linq子查询
我有以下数据库结构(简化) 贮藏 产品使用DefaultIfEmpty改进Linq子查询,linq,entity-framework,performance,Linq,Entity Framework,Performance,我有以下数据库结构(简化) 贮藏 产品 ProductId Name 费率 价格 我有产品,根据费率表,每种产品都可以有倍数的价格。我有多个商店,每个商店都有一个默认利率(rateId)。如果在给定费率(rateId)的价格表中找不到产品的价格,则返回默认rateId和产品的价格 现在,用户界面代码: public ActionResult All() { // Retrieve all products from database var produ
ProductId
Name
费率
价格
我有产品,根据费率表,每种产品都可以有倍数的价格。我有多个商店,每个商店都有一个默认利率(rateId)。如果在给定费率(rateId)的价格表中找不到产品的价格,则返回默认rateId和产品的价格
现在,用户界面代码:
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;
}
public IQueryable GetProducts(){
返回storeDB.Products
.包括(“价格”);
}
公共IQueryable GetAllStoreProducts(Guid storeId){
var store=storeDB.Stores
.SingleOrDefault(s=>s.StoreId==StoreId);
var products=GetProducts()
.其中(p=>p.Visible)
.OrderBy(p=>p.Name)
.选择(p=>new StoreProduct(){
家庭,
类别=p.类别,
MetricType=p.MetricType,
名称=p.名称,
PublicArtUrl=p.ProductArtUrl,
DateCreated=p.DateCreated,
DateUpdated=p.DateModified,
单价=单价
.Where(pc=>pc.Rate.RateId==store.RateId)
.选择(b=>b.单价)
.DefaultIfEmpty(p.Prices.FirstOrDefault(p2=>p2.Rate.IsDefault).UnitPrice)
.FirstOrDefault()
});
退货产品;
}
代码运行正常,我得到给定商店的正确价格,或者如果没有找到“覆盖”,则得到默认价格,但是。。。有没有改进linq查询性能的想法?(不想使用存储过程)- 您正在执行两个查询,它们可以组合成一个查询李>
- 仅为RateId属性选择整个商店实体李>
- 它极大地提高了查询性能。它提供查询的编译和缓存以供重用。在查询编译一次之后,您的程序可以使用其他参数执行它李>
- 选择而不是实体。实体比表示实体的简单类重得多
- 永远不要使用“包含”。这是一个真正的性能猪。只需创建一个一次获取所有信息的查询
PriceId
ProductID
RateId
UnitPrice
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);
}
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;
}