簡體   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