繁体   English   中英

针对相同的Entity Framework DbSet的两个不同的LINQ查询,均返回相同的结果

[英]Two different LINQ queries against the same Entity Framework DbSet, both return the same results

假设我有:

class ContractContext : DbContext
{
    DbSet<ACTIVITY> ACTIVITYs { get; set; }
}

我有以下代码,其中startSnapshot和endSnapshot是值为1和2的整数:

var activitiesStart = contractContext.ACTIVITYs.Where(a => a.VARIANCE_SNAPSHOT_ID == startSnapshot);
var activitiesEnd = contractContext.ACTIVITYs.Where(a => a.VARIANCE_SNAPSHOT_ID == endSnapshot);

这两个查询将返回相同的结果。 该结果将是所执行的两个查询中第一个查询的结果。 因此,如果我强迫它们都使用ToList()执行,

var activitiesStart = contractContext.ACTIVITYs.Where(a => a.VARIANCE_SNAPSHOT_ID == startSnapshot).ToList();
var activitiesEnd = contractContext.ACTIVITYs.Where(a => a.VARIANCE_SNAPSHOT_ID == endSnapshot).ToList();

然后,存储在activityEnd中的结果将是来自activityStart查询的结果。 如果我先执行activityEnd查询,则相反。 这是怎么回事? 据我所知,他们是相同的情况下,我想我可以看到,如果我创建它们在执行前两者既可能是如何组合查询。 但是,在第二种情况下,其中一个在创建另一个之前就被执行了,那么为什么要践踏第二个查询呢?

生成的SQL(两者相同):

{SELECT 
    [Extent1].[ACTIVITY_ID] AS [ACTIVITY_ID], 
    [Extent1].[ACTIVITY_NAME] AS [ACTIVITY_NAME], 
    [Extent1].[WBS_ID] AS [WBS_ID], 
    [Extent1].[VARIANCE_SNAPSHOT_ID] AS [VARIANCE_SNAPSHOT_ID], 
    [Extent1].[DUE_DATE] AS [DUE_DATE], 
    [Extent1].[IS_COMPLETE] AS [IS_COMPLETE]
FROM [p6].[ACTIVITY] AS [Extent1]
WHERE [Extent1].[VARIANCE_SNAPSHOT_ID] = @p__linq__0}

var activitiesStart = contractContext.ACTIVITYs.Where(a => a.VARIANCE_SNAPSHOT_ID == 1).ToList();
var activitiesEnd = contractContext.ACTIVITYs.Where(a => a.VARIANCE_SNAPSHOT_ID == 2).ToList();

foreach (var item in activitiesStart)
{
    Debug.Write(item.VARIANCE_SNAPSHOT_ID + " ");
}

Debug.WriteLine("");

foreach (var item in activitiesEnd)
{
    Debug.Write(item.VARIANCE_SNAPSHOT_ID + " ");
}

Debug.WriteLine("");

这将打印出两行,因为先执行activityStart。 如果我交换它们,我将得到两行一两的结果。 SQL Server Profiler显示查询已正确发送到服务器。

由于延迟执行的工作方式,在查询之间可能会产生一些干扰。 查询将在执行时针对参数的值运行(即,当参数为ToList()或以其他方式使用时)。

            var idA = 614;
            var idB = 130;

            var context = DbModel.ContextManager.Prism.dbo(DBName_Static);
            var custA = context.Customer.Where(x => x.Id == idA);
            var custB = context.Customer.Where(x => x.Id == idB);

            //different results (correct)
            var custA_forcedBefore = custA.ToList();
            var custB_forcedBefore = custB.ToList();

            //change the value of the input params to be the same
            idA = idB;

            //same results (incorrect). Because execution was deferred til after the parameter values were changed
            var custA_forcedAfter = custA.ToList();
            var custB_forcedAfter = custB.ToList();

编辑:我应该注意,当我遇到这个问题时,它并不全都在同一函数中。 在我错误地假设查询已执行之后,输入参数的值已沿堆栈向上更改。

我无法弄清楚。 我的解决方案是在执行的第一个上使用AsNoTracking。

var activitiesStart = contractContext.ACTIVITYs.AsNoTracking.Where(a => a.VARIANCE_SNAPSHOT_ID == startSnapshot).ToList();
var activitiesEnd = contractContext.ACTIVITYs.Where(a => a.VARIANCE_SNAPSHOT_ID == endSnapshot).ToList();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM