LINQ - IQueryable 优化 - 是否需要?
LINQ - IQueryable optimization - is it needed?
假设我们有一个只有几个复选框的表单(假设类似的报告 - 基于相同的 table,但过滤器不同)。
我有一个方法只需要很少的参数 - 其中 3 个对于每个报告都是通用的,其中 3 个是特定于报告的。简化版:
public IEnumerable<ReportSet> GetAList(DateTime commonDate, bool commonBoolean, TypeEnum mainReportType, AnotherTypeEnum sideType)
{
IQueryable<ReportSet> aList = this.DB.Reports;
aList = aList.FilterByDate(commonDate);
aList = aList.FilterByBool(commonBoolean);
switch(mainReportType)
{
case 1:
aList = aList.Where(x=>x..)
break;
case 2:
aList = aList.Where(x=>x..)
break;
}
return aList;
}
如果所有的复选框都被选中,我必须多次使方法成为方法的一部分(因此从 db 和 2 filterBy 获取),但我必须使用一些元组,因为我需要为每个复选框设置一组参数报告特定参数和 foreach 元组调用私有方法与我猜的开关部分。
我可以做到,但是这样做值得吗,因为这些过滤器只有一部分是可查询的? (无论如何,从数据库中获取数据都会做几次)。
有什么建议吗?
编辑:根据下面的答案,这是我的计划:
我将采用所有过滤器,构建一个查询,以获取所有想要的数据来填充所有选中的列表(但不会更多),而不是去数据库(只有一次,因为去数据库是我想这里的成本最高所以我想做这只有一次),而不是将结果拆分为我在 c# 中需要的列表。
我想我理解你的问题,但 LINQ2SQL(或与此相关的任何 LINQ)只会在需要时进行评估,而不是直接在语句/赋值上进行评估。
因此,在您的示例中,您只是构建一个(巨大的)查询,并使用 ToList() 或 foreach,它将评估您堆叠在一起的所有内容,生成一个大的 SQL 语句并将其传递给数据库进行评估。
当您启用对生成的 SQL 语句的日志记录时,您可以检查此行为:
https://msdn.microsoft.com/en-us/library/bb386961(v=vs.110).aspx
db.Log = Console.Out;
IQueryable<Customer> custQuery =
from cust in db.Customers
where cust.City == "London"
select cust;
foreach(Customer custObj in custQuery)
{
Console.WriteLine(custObj.CustomerID);
}
生成:
SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactT
itle], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Coun
try], [t0].[Phone], [t0].[Fax]
FROM [dbo].[Customers] AS [t0]
WHERE [t0].[City] = @p0
-- @p0: Input String (Size = 6; Prec = 0; Scale = 0) [London]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.20810.0
假设我们有一个只有几个复选框的表单(假设类似的报告 - 基于相同的 table,但过滤器不同)。
我有一个方法只需要很少的参数 - 其中 3 个对于每个报告都是通用的,其中 3 个是特定于报告的。简化版:
public IEnumerable<ReportSet> GetAList(DateTime commonDate, bool commonBoolean, TypeEnum mainReportType, AnotherTypeEnum sideType)
{
IQueryable<ReportSet> aList = this.DB.Reports;
aList = aList.FilterByDate(commonDate);
aList = aList.FilterByBool(commonBoolean);
switch(mainReportType)
{
case 1:
aList = aList.Where(x=>x..)
break;
case 2:
aList = aList.Where(x=>x..)
break;
}
return aList;
}
如果所有的复选框都被选中,我必须多次使方法成为方法的一部分(因此从 db 和 2 filterBy 获取),但我必须使用一些元组,因为我需要为每个复选框设置一组参数报告特定参数和 foreach 元组调用私有方法与我猜的开关部分。
我可以做到,但是这样做值得吗,因为这些过滤器只有一部分是可查询的? (无论如何,从数据库中获取数据都会做几次)。
有什么建议吗?
编辑:根据下面的答案,这是我的计划: 我将采用所有过滤器,构建一个查询,以获取所有想要的数据来填充所有选中的列表(但不会更多),而不是去数据库(只有一次,因为去数据库是我想这里的成本最高所以我想做这只有一次),而不是将结果拆分为我在 c# 中需要的列表。
我想我理解你的问题,但 LINQ2SQL(或与此相关的任何 LINQ)只会在需要时进行评估,而不是直接在语句/赋值上进行评估。
因此,在您的示例中,您只是构建一个(巨大的)查询,并使用 ToList() 或 foreach,它将评估您堆叠在一起的所有内容,生成一个大的 SQL 语句并将其传递给数据库进行评估。
当您启用对生成的 SQL 语句的日志记录时,您可以检查此行为:
https://msdn.microsoft.com/en-us/library/bb386961(v=vs.110).aspx
db.Log = Console.Out;
IQueryable<Customer> custQuery =
from cust in db.Customers
where cust.City == "London"
select cust;
foreach(Customer custObj in custQuery)
{
Console.WriteLine(custObj.CustomerID);
}
生成:
SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactT
itle], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Coun
try], [t0].[Phone], [t0].[Fax]
FROM [dbo].[Customers] AS [t0]
WHERE [t0].[City] = @p0
-- @p0: Input String (Size = 6; Prec = 0; Scale = 0) [London]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.20810.0