EF Core 2 与 EF Core 7

问题描述 投票:0回答:1

我有一个现有应用程序,已从 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 查询未获取预期数据。

c# sql entity-framework linq asp.net-core
1个回答
0
投票

查询执行可能与早期的 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 之后更改该行为。

© www.soinside.com 2019 - 2024. All rights reserved.