LINQ到SQL查询优化
我主要在java上工作,并且是LINQ的新手,所以我需要一些关于这个查询性能的建议LINQ到SQL查询优化,linq,linq-to-sql,Linq,Linq To Sql,我主要在java上工作,并且是LINQ的新手,所以我需要一些关于这个查询性能的建议 1. Products --> ProductID | Name | Price | VendorID 2. Category --> CategoryID | Label 3. SubCategory--> SubCategoryID | Label | ParentID 4. Pro
1. Products --> ProductID | Name | Price | VendorID
2. Category --> CategoryID | Label
3. SubCategory--> SubCategoryID | Label | ParentID
4. Product_SubCategory_Mapping--> ProductID | SubCategoryID
5. Vendor --> VendorID | VendorName
我想从product表中为任何给定子类别选择所有产品及其供应商。下面的查询可以正常工作吗?或者它需要任何优化
var list = (from p in Products
join cat in Product_SubCategory_Mapping
on p.UserId equals cat.UserId
join sub in SubCategories
on cat.SubCategoryId equals sub.SubCategoryId
where sub.CategoryId == 19 && CustomFunction(p.ID) > 100
select new { p, p.Vendor, trend = CustomFunction(p.ID) })
.Skip((pageNum - 1) * pageSize)
.Take(pageSize);
我将创建一个自定义类,该类将匹配查询结果
您的思路是正确的,但是LINQ to SQL无法理解
CustomFunction()
,因此您需要使用AsEnumerable()
切换到LINQ to对象,然后才能调用它。您还可以使用let
捕获CustomFunction()
的结果一次,以便在查询中的其他位置使用:
var listFromSql = from p in Products
join cat in Product_SubCategory_Mapping
on p.UserId equals cat.UserId
join sub in SubCategories
on cat.SubCategoryId equals sub.SubCategoryId
where sub.CategoryId == 19
select p;
var list = from p in listFromSql.AsEnumerable()
let trend = CustomFunction(p.ID)
where trend > 100
select new { p, p.Vendor, trend };
更新:回答您列出的问题:
let
IQueryable
上的Skip()
和Take()
(如上面的listFromSql
)将转换为适当的SQL,从而限制通过线路发送的结果集<在IEnumerable
上的code>Skip()和Take()
只需枚举序列以获得请求的结果,但对SQL返回的完整结果集进行操作您的思路是正确的,但是LINQ to SQL无法理解
CustomFunction()
,因此您需要使用AsEnumerable()
切换到LINQ to对象,然后才能调用它。您还可以使用let
捕获CustomFunction()
的结果一次,以便在查询中的其他位置使用:
var listFromSql = from p in Products
join cat in Product_SubCategory_Mapping
on p.UserId equals cat.UserId
join sub in SubCategories
on cat.SubCategoryId equals sub.SubCategoryId
where sub.CategoryId == 19
select p;
var list = from p in listFromSql.AsEnumerable()
let trend = CustomFunction(p.ID)
where trend > 100
select new { p, p.Vendor, trend };
更新:回答您列出的问题:
let
IQueryable
上的Skip()
和Take()
(如上面的listFromSql
)将转换为适当的SQL,从而限制通过线路发送的结果集<在IEnumerable
上的code>Skip()和Take()
只需枚举序列以获得请求的结果,但对SQL返回的完整结果集进行操作因为CustomFunction是数据库中的ScalarFunction,所以LINQ to SQL应该能够有效地评估它。您可能希望使用LET提取一次该值,但请检查生成的SQL和查询执行计划,看看它是否提供了任何改进,或者SQL Server是否在内部自动进行了适当的优化
var list = (from p in Products
join cat in Product_SubCategory_Mapping
on p.UserId equals cat.UserId
join sub in SubCategories
on cat.SubCategoryId equals sub.SubCategoryId
let trend = CustomFunction(p.ID)
where sub.CategoryId == 19 && trend > 100
select new { p, p.Vendor, trend })
.Skip((pageNum - 1) * pageSize)
.Take(pageSize);
如果元素之间存在关联,则可能希望使用它们而不是联接。它不会改变生成的查询(很多),但可能更易于维护,因为连接是由模型中建立的关联抽象出来的
var list = (from p in Products
from cat in p.Product_SubCategory_Mappings
let trend = CustomFunction(p.ID)
where cat.SubCategory.CategoryId == 19 && trend > 100
select new { Product = p, p.Vendor, trend})
.Skip(pageNum - 1) * pageSize)
.Take(pageSize);
因为CustomFunction是数据库中的ScalarFunction,所以LINQ to SQL应该能够有效地评估它。您可能希望使用LET提取一次该值,但请检查生成的SQL和查询执行计划,看看它是否提供了任何改进,或者SQL Server是否在内部自动进行了适当的优化
var list = (from p in Products
join cat in Product_SubCategory_Mapping
on p.UserId equals cat.UserId
join sub in SubCategories
on cat.SubCategoryId equals sub.SubCategoryId
let trend = CustomFunction(p.ID)
where sub.CategoryId == 19 && trend > 100
select new { p, p.Vendor, trend })
.Skip((pageNum - 1) * pageSize)
.Take(pageSize);
如果元素之间存在关联,则可能希望使用它们而不是联接。它不会改变生成的查询(很多),但可能更易于维护,因为连接是由模型中建立的关联抽象出来的
var list = (from p in Products
from cat in p.Product_SubCategory_Mappings
let trend = CustomFunction(p.ID)
where cat.SubCategory.CategoryId == 19 && trend > 100
select new { Product = p, p.Vendor, trend})
.Skip(pageNum - 1) * pageSize)
.Take(pageSize);
忘记提到CustomFunction是数据库中的自定义函数。LINQ的陈述仍然无法识别它吗?我在LINQPAD中使用过它,我从来没有在自定义函数中使用过L2SQL——如果它在LINQPAD中工作,我希望它在任何地方都能工作。它与
let
一起工作吗?是的,我是这样使用它的:(从u中的用户加入u.UserId上的业务类别中的cat.UserId等于cat.UserId加入cat.subcategory上的子类别中的sub.subcategory id等于sub.subcategory id let trend=calculatedInstance(u.Zipcode,“07306”)其中sub.CategoryId==19&&trendLINQ to SQL支持标量函数和表值函数。EF在这里有更多限制。忘了提到CustomFunction是数据库中的自定义函数。LINQ语句仍然无法识别它?我使用LINQPAD,它工作得很好。我从未将L2SQL用于自定义函数-如果它在LINQP中工作的话AD我希望它在任何地方都能工作。它与let
一起工作吗?是的,我这样使用它:(从u中的用户在u.UserId上加入业务类别中的cat.UserId在cat.subcategory上加入子类别中的sub.subcategory id等于sub.subcategory id let trend=calculatedInstance(u.Zipcode,“07306”)其中sub.CategoryId==19&&trendLINQ to SQL支持标量和表值函数。EF在这里有更多限制。请简要说明一下(因为我的LINQ技能很弱,我无法提供任何有用的建议来实际回答您的问题)…但我忍不住注意到,您的products表有一个ProductID列,而其他两个表只有一个ID列。我猜这些列代表一个主键字段(可能也代表一个标识字段)如果是这样,您可能需要考虑在所有表中使名称一致:IE、Realy.CyryYID或Studio.StudioD>产品。ID。对于供应商和子类别,同意。谢谢建议。我更改了名称。我的实际数据库有正确的名称。只是一个快速注释。(因为我的LINQ技能很弱,我无法提供任何有用的建议来回答你的问题)…但我不能不