我有一个现有应用程序,已从 Entity Framework Core 2 迁移到 Entity Framework Core 7。在 EF Core 2 版本中,我有一个可以正确检索数据的 LINQ 查询,但在迁移到 EF Core 7 后,相同的查询没有返回预期的结果。
(
from proposal in context.Proposal
join proposalRatingROI in context.ProposalRatingROI
on proposal.ProposalId equals proposalRatingROI.ProposalId
join proposalAssets in context.ProposalAssets
on proposalRatingROI.ExpectedProposalAssetid equals proposalAssets.ProposalAssetId
into expectedProposalAssetData
from expectedProposalAssetInfo in expectedProposalAssetData.DefaultIfEmpty()
join proposalAssets in context.ProposalAssets
on proposalRatingROI.ActualProposalAssetid equals proposalAssets.ProposalAssetId
into actualProposalAssetData
from actualProposalAssetInfo in actualProposalAssetData.DefaultIfEmpty()
where
proposal.ProposalId == proposalId
&& proposal.IsDeleted == false
&& expectedProposalAssetInfo.IsDeleted == false
&& actualProposalAssetInfo.IsDeleted == false
select new ProposalROIRatingModel
{
ProposalRatingROIId = proposalRatingROI.ProposalRatingROIId,
ProposalId = proposalRatingROI.ProposalId,
ExpectedLocalRating = proposalRatingROI.ExpectedLocalRating,
ExpectedArabRating = proposalRatingROI.ExpectedArabRating,
ExpectedLocalArabRating = proposalRatingROI.ExpectedLocalArabRating,
ExpectedAge = proposalRatingROI.ExpectedAge,
ExpectedKSARating = proposalRatingROI.ExpectedKSARating,
ExpectedOtherRating = proposalRatingROI.ExpectedOtherRating,
ActualLocalRating = proposalRatingROI.ActualLocalRating,
ActualArabRating = proposalRatingROI.ActualArabRating,
ActualLocalArabRating = proposalRatingROI.ActualLocalArabRating,
ActualAge = proposalRatingROI.ActualAge,
ActualKSARating = proposalRatingROI.ActualKSARating,
ActualOtherRating = proposalRatingROI.ActualOtherRating,
UserId = proposalRatingROI.UserId,
ExpectedProposalAssetid = proposalRatingROI.ExpectedProposalAssetid,
ActualProposalAssetid = proposalRatingROI.ActualProposalAssetid,
ExpectedFilename = expectedProposalAssetInfo.Filename,
ActualFilename = actualProposalAssetInfo.Filename,
UpdatedBy = proposalRatingROI.UpdatedBy
}
).ToList();
在 EF7 中我得到这个 sql
exec sp_executesql N'
SELECT
[p0].[proposalratingroiid] AS [ProposalRatingROIId],
[p0].[proposalid] AS [ProposalId],
[p0].[expectedlocalrating] AS [ExpectedLocalRating],
[p0].[expectedarabrating] AS [ExpectedArabRating],
[p0].[expectedlocalarabrating] AS [ExpectedLocalArabRating],
[p0].[expectedage] AS [ExpectedAge],
[p0].[expectedksarating] AS [ExpectedKSARating],
[p0].[expectedotherrating] AS [ExpectedOtherRating],
[p0].[actuallocalrating] AS [ActualLocalRating],
[p0].[actualarabrating] AS [ActualArabRating],
[p0].[actuallocalarabrating] AS [ActualLocalArabRating],
[p0].[actualage] AS [ActualAge],
[p0].[actualksarating] AS [ActualKSARating],
[p0].[actualotherrating] AS [ActualOtherRating],
[p0].[userid] AS [UserId],
[p0].[expectedproposalassetid] AS [ExpectedProposalAssetid],
[p0].[actualproposalassetid] AS [ActualProposalAssetid],
[p1].[filename] AS [ExpectedFilename],
[p2].[filename] AS [ActualFilename],
[p0].[updatedby] AS [UpdatedBy]
FROM
[proposals] AS [p]
INNER JOIN [proposalratingroi] AS [p0] ON [p].[proposalid] = [p0].[proposalid]
LEFT JOIN [proposalassets] AS [p1] ON [p0].[expectedproposalassetid] = [p1].[proposalassetid]
LEFT JOIN [proposalassets] AS [p2] ON [p0].[actualproposalassetid] = [p2].[proposalassetid]
WHERE
[p].[proposalid] = @__8__locals1_proposalId_0
AND [p].[isdeleted] = CAST(0 AS bit)
AND [p1].[isdeleted] = CAST(0 AS bit)
AND [p2].[isdeleted] = CAST(0 AS bit) ',
N'@__8__locals1_proposalId_0 int',@__8__locals1_proposalId_0=0000
在 ef2 中
exec sp_executesql N'
SELECT
[proposalRatingROI].[proposalratingroiid],
[proposalRatingROI].[proposalid],
[proposalRatingROI].[expectedlocalrating],
[proposalRatingROI].[expectedarabrating],
[proposalRatingROI].[expectedlocalarabrating],
[proposalRatingROI].[expectedage],
[proposalRatingROI].[expectedksarating],
[proposalRatingROI].[expectedotherrating],
[proposalRatingROI].[actuallocalrating],
[proposalRatingROI].[actualarabrating],
[proposalRatingROI].[actuallocalarabrating],
[proposalRatingROI].[actualage],
[proposalRatingROI].[actualksarating],
[proposalRatingROI].[actualotherrating],
[proposalRatingROI].[userid],
[proposalRatingROI].[expectedproposalassetid],
[proposalRatingROI].[actualproposalassetid],
[proposalAssets].[filename] AS [ExpectedFilename],
[proposalAssets0].[filename] AS [ActualFilename],
[proposalRatingROI].[updatedby]
FROM
[proposals] AS [proposal]
INNER JOIN [proposalratingroi] AS [proposalRatingROI] ON [proposal].[proposalid] = [proposalRatingROI].[proposalid]
LEFT JOIN [proposalassets] AS [proposalAssets] ON [proposalRatingROI].[expectedproposalassetid] = [proposalAssets].[proposalassetid]
LEFT JOIN [proposalassets] AS [proposalAssets0] ON [proposalRatingROI].[actualproposalassetid] = [proposalAssets0].[proposalassetid]
WHERE
(
(
(
[proposal].[proposalid] = @__8__locals1_proposalId_0
)
AND ([proposal].[isdeleted] = 0)
)
AND (
CASE WHEN [proposalAssets].[isdeleted] = 1 THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END = 0
)
)
AND (
CASE WHEN [proposalAssets0].[isdeleted] = 1 THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END = 0
),
N'@__8__locals1_proposalId_0 int',@__8__locals1_proposalId_0=0000
我希望 EF7 查询返回与 EF2 查询相同的结果,因为 SQL 翻译看起来很相似。但是,EF7 查询未获取预期数据。
查询执行可能与早期的 EF Core 实现相比,围绕 LEFT JOIN 可选关系中标志的比较发生了变化。 ProposalAssets 上的 IsDeleted 标志可以为空吗?
假设不是,但您只想考虑没有资产或资产未删除(错误)的情况,则考虑将查询更改为:
&& expectedProposalAssetInfo?.IsDeleted == false
&& actualProposalAssetInfo?.IsDeleted == false
虽然没有记忆,但我不能 100% 确定
?.
是否允许可空性检查,您可能需要:
&& (expectedProposalAssetInfo == null || expectedProposalAssetInfo.IsDeleted == false)
&& (actualProposalAssetInfo == null || actualProposalAssetInfo.IsDeleted == false)
...作为最坏的情况。有人可能会在 EF Core 中查找 RFC 或类似内容,以在 EF Core 2 之后更改该行为。