我正在运行像
这样的linq查询dbEntity.Where(x => x.FundType== "E")
.Where(x => x.ReportDate == new DateTime(2014,10,23))
.GroupBy(x => x.ReportDate)
.Select(groupedDate => new CategorySourceData
{
ReportDate = groupedDate.Key,
TotalFlow = groupedDate.Sum(x => x.Flow)
}
.ToList();
我希望它能给我与此查询相同的结果以及类似的运行时
select ReportDate,
sum(flow)
from vwDailyFundFlowDetail
where FundType = 'E'
group by ReportDate
Ef生成一个返回正确数据的查询。但是,我的hanwritten查询在我的测试集上需要大约13秒,并且ef生成的查询在同一测试集上需要24秒。
ef查询看起来像
exec sp_executesql N'SELECT
1 AS [C1],
[GroupBy1].[K1] AS [ReportDate],
CAST( [GroupBy1].[A1] AS real) AS [C2]
FROM ( SELECT
[Extent1].[ReportDate] AS [K1],
SUM([Extent1].[Flow]) AS [A1]
FROM (SELECT
[vwDailyFundFlowDetail].[HFundId] AS [HFundId],
[vwDailyFundFlowDetail].[ReportDate] AS [ReportDate],
[vwDailyFundFlowDetail].[Flow] AS [Flow],
[vwDailyFundFlowDetail].[ForexChange] AS [ForexChange],
[vwDailyFundFlowDetail].[AssetsEnd] AS [AssetsEnd],
[vwDailyFundFlowDetail].[ShareID] AS [ShareID],
[vwDailyFundFlowDetail].[ShareClass] AS [ShareClass],
[vwDailyFundFlowDetail].[ISIN] AS [ISIN],
[vwDailyFundFlowDetail].[CUSIP] AS [CUSIP],
[vwDailyFundFlowDetail].[Ticker] AS [Ticker],
[vwDailyFundFlowDetail].[AssetsStart] AS [AssetsStart],
[vwDailyFundFlowDetail].[PortfolioChange] AS [PortfolioChange],
[vwDailyFundFlowDetail].[FundName] AS [FundName],
[vwDailyFundFlowDetail].[SSID] AS [SSID],
[vwDailyFundFlowDetail].[Advisor] AS [Advisor],
[vwDailyFundFlowDetail].[GEOID] AS [GEOID],
[vwDailyFundFlowDetail].[FTCID] AS [FTCID],
[vwDailyFundFlowDetail].[BenchIndex] AS [BenchIndex],
[vwDailyFundFlowDetail].[FundType] AS [FundType],
[vwDailyFundFlowDetail].[ETF] AS [ETF],
[vwDailyFundFlowDetail].[Domicile] AS [Domicile],
[vwDailyFundFlowDetail].[GeographicFocus] AS [GeographicFocus],
[vwDailyFundFlowDetail].[Currency] AS [Currency],
[vwDailyFundFlowDetail].[FundDomicile] AS [FundDomicile],
[vwDailyFundFlowDetail].[Manager] AS [Manager],
[vwDailyFundFlowDetail].[FundCurrency] AS [FundCurrency],
[vwDailyFundFlowDetail].[Benchmark] AS [Benchmark],
[vwDailyFundFlowDetail].[FundFocus] AS [FundFocus],
[vwDailyFundFlowDetail].[NetChange] AS [NetChange],
[vwDailyFundFlowDetail].[FundId] AS [FundId],
[vwDailyFundFlowDetail].[InstOrRetail] AS [InstOrRetail],
[vwDailyFundFlowDetail].[Hedge_yn] AS [Hedge_yn],
[vwDailyFundFlowDetail].[SRI_yn] AS [SRI_yn],
[vwDailyFundFlowDetail].[SCID] AS [SCID],
[vwDailyFundFlowDetail].[DistributorId] AS [DistributorId],
[vwDailyFundFlowDetail].[Distributor] AS [Distributor],
[vwDailyFundFlowDetail].[Frontier] AS [Frontier],
[vwDailyFundFlowDetail].[FundCategory] AS [FundCategory],
[vwDailyFundFlowDetail].[Commodity] AS [Commodity],
[vwDailyFundFlowDetail].[CurrId] AS [CurrId],
[vwDailyFundFlowDetail].[Idx] AS [Idx],
[vwDailyFundFlowDetail].[Bear] AS [Bear],
[vwDailyFundFlowDetail].[Dividend] AS [Dividend],
[vwDailyFundFlowDetail].[AbsoluteReturn] AS [AbsoluteReturn],
[vwDailyFundFlowDetail].[Islamic_yn] AS [Islamic_yn],
[vwDailyFundFlowDetail].[Ins] AS [Ins],
[vwDailyFundFlowDetail].[Inf] AS [Inf],
[vwDailyFundFlowDetail].[Silver] AS [Silver],
[vwDailyFundFlowDetail].[Gold] AS [Gold],
[vwDailyFundFlowDetail].[AG] AS [AG],
[vwDailyFundFlowDetail].[Metal] AS [Metal],
[vwDailyFundFlowDetail].[Administrator] AS [Administrator],
[vwDailyFundFlowDetail].[Custodian] AS [Custodian],
[vwDailyFundFlowDetail].[Bear2x] AS [Bear2x],
[vwDailyFundFlowDetail].[Bear3x] AS [Bear3x],
[vwDailyFundFlowDetail].[Leverage1x] AS [Leverage1x],
[vwDailyFundFlowDetail].[Leverage2x] AS [Leverage2x],
[vwDailyFundFlowDetail].[MuniStateId] AS [MuniStateId],
[vwDailyFundFlowDetail].[Leverage3x] AS [Leverage3x],
[vwDailyFundFlowDetail].[Synthetic_ETF] AS [Synthetic_ETF],
[vwDailyFundFlowDetail].[Physical_ETF] AS [Physical_ETF],
[vwDailyFundFlowDetail].[IG] AS [IG],
[vwDailyFundFlowDetail].[EMC] AS [EMC],
[vwDailyFundFlowDetail].[EMS] AS [EMS],
[vwDailyFundFlowDetail].[EMM] AS [EMM],
[vwDailyFundFlowDetail].[MuniState] AS [MuniState],
[vwDailyFundFlowDetail].[FundQualityId] AS [FundQualityId],
[vwDailyFundFlowDetail].[FundDurationId] AS [FundDurationId],
[vwDailyFundFlowDetail].[QualityName] AS [QualityName],
[vwDailyFundFlowDetail].[DurationName] AS [DurationName],
[vwDailyFundFlowDetail].[ClosedEnd] AS [ClosedEnd],
[vwDailyFundFlowDetail].[MLP] AS [MLP],
[vwDailyFundFlowDetail].[ArrivalTime] AS [ArrivalTime],
[vwDailyFundFlowDetail].[ArrivalDayCode] AS [ArrivalDayCode],
[vwDailyFundFlowDetail].[DActivationDate] AS [DActivationDate],
[vwDailyFundFlowDetail].[WActivationDate] AS [WActivationDate],
[vwDailyFundFlowDetail].[MActivationDate] AS [MActivationDate],
[vwDailyFundFlowDetail].[ShareClassCurrency] AS [ShareClassCurrency]
FROM [dbo].[vwDailyFundFlowDetail] AS [vwDailyFundFlowDetail]) AS [Extent1]
WHERE ((@p__linq__0 IS NULL) OR ([Extent1].[FundType] = @p__linq__1) OR (([Extent1].[FundType] IS NULL) AND (@p__linq__1 IS NULL))) AND (0 = (CASE WHEN ( EXISTS (SELECT
1 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
WHERE 1 = 0
)) THEN cast(1 as bit) ELSE cast(0 as bit) END))
GROUP BY [Extent1].[ReportDate]
) AS [GroupBy1]',N'@p__linq__0 nvarchar(4000),@p__linq__1 varchar(8000)',@p__linq__0=N'E',@p__linq__1='E'
where子句的一部分
AND (0 = (CASE WHEN ( EXISTS (SELECT
1 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
WHERE 1 = 0
)) THEN cast(1 as bit) ELSE cast(0 as bit) END))
似乎是主要问题。据我所知,case语句总是0,所以这总是正确的。这部分查询的存在是从
更改执行计划的单个部分 看起来像如果我从where子句中删除case语句,那么这个查询的执行计划和运行时间以及我手写的sql就我所知道的那样变得相同。如何阻止EF添加where子句的这一部分?我在linq代码中做了什么让EF将其添加到查询中?
答案 0 :(得分:2)
您需要在Configuration.UseDatabaseNullSemantics = true;
DBContext
这会阻止添加的is null
支票
答案 1 :(得分:0)
我有类似的问题。
我猜你首先使用Datebase和EDMX文件。因此,请检查您的映射不是DefiningQuery
。
打开EDMX并找到如下字符串:
<EntitySet Name="vwDailyFundFlowDetail" EntityType="yourbase.Store.vwDailyFundFlowDetail" store:Type="Tables" store:Schema="dbo" store:Name="vwDailyFundFlowDetail">
<DefiningQuery>SELECT
[vwDailyFundFlowDetail].[HFundId] AS [HFundId],
[vwDailyFundFlowDetail].[ReportDate] AS [ReportDate],
[vwDailyFundFlowDetail].[Flow] AS [Flow],
[vwDailyFundFlowDetail].[ForexChange] AS [ForexChange],
[vwDailyFundFlowDetail].[AssetsEnd] AS [AssetsEnd],
[vwDailyFundFlowDetail].[ShareID] AS [ShareID],
//...others
FROM [dbo].[vwDailyFundFlowDetail] AS [vwDailyFundFlowDetail]</DefiningQuery>
</EntitySet>
用这样的smth替换它:
<EntitySet Name="vwDailyFundFlowDetail" EntityType="yourbase.Store.vwDailyFundFlowDetail" store:Type="Tables" Schema="dbo" />
检查,如果FundType必须可以为空。如果不是 - 将其标记为explicitly
不可为空:
我认为,它会有所帮助,以后我们可以研究新生成的查询。