假设我有:
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("");
这会打印出两行 1,因为 activitiesStart 首先执行。如果我交换它们,我会得到两排两两。 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();
编辑:我应该注意到,当我遇到这个问题时,它并不都是在同一个函数中。在我错误地假设查询已经执行之后,输入参数的值在堆栈中被更改了。
关于c# - 针对同一个 Entity Framework DbSet 的两个不同的 LINQ 查询,都返回相同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37999463/