我写过这样的查询:
using (var _db = new LuxedecorContext())
{
var items = (from navItem in _db.NavItems
join dealItem in _db.Deal_Items
on navItem.ItemWebCode equals dealItem.ItemWebCode
join mainCategory in _db.Web_MainCategory
on new { A = navItem.Website, B = navItem.MainCategory }
equals new { A = mainCategory.Website, B = mainCategory.Code }
join subCategory in _db.Web_SubCategory
on new { A = navItem.Website, B = navItem.MainCategory, C = navItem.SubCategory }
equals new { A = subCategory.Website, B = subCategory.CodeMain, C = subCategory.Code }
select new
{
SalePrice = navItem.SalePrice,
Vendor = navItem.Vendor,
Promo = navItem.Promo,
Description = navItem.Description,
FreightMax = navItem.FreightMax,
ItemImage = navItem.ItemImage,
ItemImage2 = navItem.ItemImage2,
StrikedPrice = (navItem.RetailPrice ?? 0) * (1 - (navItem.PercentOff ?? 0) / 100) / (1 - navItem.PercentOffShow / 100),
ItemId = navItem.ItemID,
StockQty = navItem.StockQty,
SeoURL = navItem.SeoURL,
DealSequence = dealItem.Sequence,
DealId = dealItem.DealID,
Website = navItem.Website
}).Where(x => x.SeoURL != string.Empty && x.DealId == dealId).GroupBy(x=>x.ItemId).Select(x=>x.FirstOrDefault());
if(onlyAvalaibleItems)
items = items.Where(x => x.StockQty != "0");
switch(sort)
{
case "PriceAsc":
items = items.OrderBy(x => x.SalePrice);
break;
case "PriceDesc":
items = items.OrderByDescending(x => x.SalePrice);
break;
case "DescriptionAsc":
items = items.OrderBy(x => x.Description.Replace(x.Vendor, "").Trim());
break;
case "DescriptionDesc":
items = items.OrderByDescending(x => x.Description.Replace(x.Vendor, "").Trim());
break;
default:
items = items.OrderBy(x=>x.DealSequence);
break;
}
return await items.Select(x => new ProductCollectionItem
{
SalePrice = x.SalePrice,
Vendor = x.Vendor,
Promo = x.Promo,
Description = x.Description,
FreightMax = x.FreightMax,
ItemImage = x.ItemImage,
ItemImage2 = x.ItemImage2,
StrikedPrice = x.StrikedPrice ?? 0
}).ToListAsync();
}
这是SQL,我有:
SELECT
[Project4].[C1] AS [C1],
[Project4].[SalePrice] AS [SalePrice],
[Project4].[Vendor] AS [Vendor],
[Project4].[Promo] AS [Promo],
[Project4].[Description] AS [Description],
[Project4].[FreightMax] AS [FreightMax],
[Project4].[ItemImage] AS [ItemImage],
[Project4].[ItemImage2] AS [ItemImage2],
[Project4].[C2] AS [C2]
FROM ( SELECT
1 AS [C1],
CASE WHEN ([Limit1].[C1] IS NULL) THEN cast(0 as decimal(18)) ELSE [Limit1].[C1] END AS [C2],
[Limit1].[Description] AS [Description],
[Limit1].[SalePrice] AS [SalePrice],
[Limit1].[ItemImage] AS [ItemImage],
[Limit1].[ItemImage2] AS [ItemImage2],
[Limit1].[Vendor] AS [Vendor],
[Limit1].[Promo] AS [Promo],
[Limit1].[FreightMax] AS [FreightMax],
[Limit1].[Sequence] AS [Sequence]
FROM (SELECT
@p__linq__0 AS [p__linq__0],
@p__linq__1 AS [p__linq__1],
[Distinct1].[ItemID] AS [ItemID]
FROM ( SELECT DISTINCT
[Extent1].[ItemID] AS [ItemID]
FROM [dbo].[NavItems] AS [Extent1]
INNER JOIN [dbo].[Deal_Items] AS [Extent2] ON [Extent1].[ItemWebCode] = [Extent2].[ItemWebCode]
INNER JOIN [dbo].[Web_MainCategory] AS [Extent3] ON ([Extent1].[Website] = [Extent3].[Website]) AND ([Extent1].[MainCategory] = [Extent3].[Code])
INNER JOIN [dbo].[Web_SubCategory] AS [Extent4] ON ([Extent1].[Website] = [Extent4].[Website]) AND ([Extent1].[MainCategory] = [Extent4].[CodeMain]) AND ([Extent1].[SubCategory] = [Extent4].[Code])
WHERE ( NOT (([Extent1].[SeoURL] = @p__linq__0) AND ((CASE WHEN ([Extent1].[SeoURL] IS NULL) THEN cast(1 as bit) ELSE cast(0 as bit) END) = (CASE WHEN (@p__linq__0 IS NULL) THEN cast(1 as bit) ELSE cast(0 as bit) END)))) AND ([Extent2].[DealID] = @p__linq__1)
) AS [Distinct1] ) AS [Project2]
OUTER APPLY (SELECT TOP (1)
[Extent5].[Description] AS [Description],
[Extent5].[SalePrice] AS [SalePrice],
[Extent5].[ItemImage] AS [ItemImage],
[Extent5].[ItemImage2] AS [ItemImage2],
[Extent5].[Vendor] AS [Vendor],
[Extent5].[Promo] AS [Promo],
[Extent5].[FreightMax] AS [FreightMax],
[Extent6].[Sequence] AS [Sequence],
((CASE WHEN ([Extent5].[RetailPrice] IS NULL) THEN cast(0 as decimal(18)) ELSE [Extent5].[RetailPrice] END) * (cast(1 as decimal(18)) - ((CASE WHEN ([Extent5].[PercentOff] IS NULL) THEN cast(0 as decimal(18)) ELSE [Extent5].[PercentOff] END) / cast(100 as decimal(18))))) / (cast(1 as decimal(18)) - ([Extent5].[PercentOffShow] / cast(100 as decimal(18)))) AS [C1]
FROM [dbo].[NavItems] AS [Extent5]
INNER JOIN [dbo].[Deal_Items] AS [Extent6] ON [Extent5].[ItemWebCode] = [Extent6].[ItemWebCode]
INNER JOIN [dbo].[Web_MainCategory] AS [Extent7] ON ([Extent5].[Website] = [Extent7].[Website]) AND ([Extent5].[MainCategory] = [Extent7].[Code])
INNER JOIN [dbo].[Web_SubCategory] AS [Extent8] ON ([Extent5].[Website] = [Extent8].[Website]) AND ([Extent5].[MainCategory] = [Extent8].[CodeMain]) AND ([Extent5].[SubCategory] = [Extent8].[Code])
WHERE ( NOT (([Extent5].[SeoURL] = @p__linq__0) AND ((CASE WHEN ([Extent5].[SeoURL] IS NULL) THEN cast(1 as bit) ELSE cast(0 as bit) END) = (CASE WHEN (@p__linq__0 IS NULL) THEN cast(1 as bit) ELSE cast(0 as bit) END)))) AND ([Extent6].[DealID] = @p__linq__1) AND ([Project2].[ItemID] = [Extent5].[ItemID]) ) AS [Limit1]
) AS [Project4]
ORDER BY [Project4].[Sequence] ASC
旧数据库中没有任何关系。我正在使用大多数连接来剪切我不需要的数据。我想知道:这是一个好方法吗?如何优化查询?
答案 0 :(得分:1)
我总是不想使用连接进行过滤。有两个原因:
Join
传达您希望通过联接表中的字段扩展结果集。另一方面,Any
(或SQL中的EXISTS
)准确地传达了您想要的内容:过滤。换句话说:使用使代码不言自明的方法。如果你只有1..n-1关联的加入(我假设),只有第二个原因重要,因为性能不应该有太大差异。对我来说,第二个原因是令人信服的。
附注:即使数据库没有硬外键,我强烈建议您在EF模型中定义关联(导航属性)。如果你这样做,你可以使用像
这样的代码from navItem in _db.NavItems
where navItem.DealItem != null
或者将(伪)外键作为属性拉入类模型中,这样就可以了
from navItem in _db.NavItems
where navItem.ItemWebCode.HasValue