c# - 针对同一个 Entity Framework DbSet 的两个不同的 LINQ 查询,都返回相同的结果

标签 c# entity-framework linq

假设我有:

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/

相关文章:

c# - 测试事件监听器

c# - 太多的多边形 : XNA Framework Reach profile does not support 32 bit indices

c# - 长事务的死锁

c# - Entity Framework 4 中的简单条件 LINQ 查询

JavaScript 查找数组中的单个元素

c# - LINQ - 加入 3 个表与分组和求和

c# - 如何在 ASP.NET MVC3 中填充 ViewModel

c# - 为什么会出现序列化错误?

c# - 如何以 RESTful 方式表示/维护主要细节关系?

c# - LINQ to Entities 根据结果拆分字符串