假设我有:
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();
然后存储在activitiesEnd中的结果将是activitiesStart查询的结果。如果我先执行activitiesEnd查询,那么反之亦然。发生了什么事?我知道它们是相同的上下文,我想我可以看到可能如何在执行之前创建它们时如何组合查询。然而,在第二种情况下,一个在另一个被创建之前执行,那么为什么它会践踏第二个查询呢?
生成的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("");
这会输出两行,因为activitiesStart是先执行的。如果我换掉它们,我会得到两排两个。 SQL Server Profiler显示查询已正确发送到服务器。
答案 0 :(得分:0)
由于延迟执行的工作方式,可能会在查询之间产生一些串扰。查询将在执行时针对参数的值运行(即,当它是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();
编辑:我应该注意到,当我遇到这个问题时,它不是全部都在同一个函数中。在错误地假设查询已经执行之后,输入参数的值已经在堆栈中改变了。
答案 1 :(得分:0)
我无法解决这个问题。我的解决方案是在第一个执行的时候使用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();