2016-06-23 2 views
2

내가 가진 가정 반환두 개의 서로 다른 LINQ 쿼리는 모두 동일한 결과

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

두 쿼리는 동일한 결과를 반환합니다. 그 결과는 실행되는 두 개의 쿼리 중 첫 번째 쿼리 결과입니다. 내가 그들을 강제한다면 모두

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 쿼리의 결과가 될 것이다하는 ToList()를 실행합니다. activitiesEnd 쿼리를 먼저 실행하면 그 반대가 true가됩니다. 무슨 일이야? 나는 그것들이 같은 문맥이라는 것을 이해한다. 나는 그것들이 실행되기 전에 그것들을 모두 생성한다면 그것들이 어떻게 생성되는지를 이 어떻게 조합 할 수 있는지를 알 수 있다고 생각한다. 그러나 두 번째 경우에는 하나가 실행되어 다른 하나가 생성되기 전에 왜 두 번째 쿼리를 짓밟습니까? (모두 동일)

생성 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 프로파일 러는 쿼리가 서버에 제대로 보내 졌음을 보여줍니다.

+0

startSnapshot 및 endSnapshot의 값은 무엇입니까? 어떻게 배정 받습니까? –

+0

서로 영향을 줄 이유가 없습니다. 첫 번째 문장까지 디버깅 할 때 startSnapshot 및 endSnapShot의 값은 무엇입니까? – sovemp

+0

함수에 대한 매개 변수이며, 테스트 케이스에서는 1 (시작)과 2 (끝)입니다. 나는 그 질문을 갱신 할 것이다. –

답변

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(); 
+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(); 

편집 : 나는이 문제점에 부딪혔을 때 모든 기능이 동일한 것은 아니라는 점에 유의해야합니다. 입력 매개 변수의 값은 쿼리가 이미 실행되었다고 잘못 가정 한 후에 스택으로 바뀌 었습니다.

+0

이것은 완전히 이해가됩니다. EF가 매개 변수의 값이 아니라 매개 변수에 대한 참조를 바인딩한다고 생각합니다. 그러나 내 게시물에서 세 번째 코드 블록을 보면 다른 변수를 사용하여 쿼리를 실행하고 있음을 알 수 있습니다. 내가 다른 사람과 동등해질 때가 결코 없다. 또한 값을 하드 코드 한 예제 섹션을 보면 동일한 문제가 발생합니다. –

+0

@TomSchultz 즉각적인 ToList()를 수행하고 sql 프로필러에서 매개 변수 값을 확인 했으므로 지연된 실행 매개 변수 값 문제가 아니라는 점에 동의하는 경향이 있습니다. 그것은 기이 한 이상한 곳입니다. – Derpy

관련 문제