2009-11-04 14 views
1

저는 Entity Framework를 사용하고 있으며 COMMENT 엔터티가 있습니다. COMMENT에는 Nullable Date 인 DATEMODIFIED 속성이 있습니다. 심지어ObjectQuery.Where의 DateTime 비교

Dim q As ObjectQuery(Of COMMENT) = _ 
    (From c In model.COMMENT Select c) 

If startDate.HasValue Then 
    q = q.Where(Function(c) startDate.Value <= c.DATEMODIFIED) 
End If 

문제는 q.toList()는 의견이 반환되지 않는다는 점이다 : 나는 날짜별로 주석을 필터링하는 쿼리를 작성하기 위해 노력하고있어, 그래서 startDate를 객체를 생성하고, 다음을 수행 나는 그것이해야한다고 생각하지만. 데이터베이스의 모든 주석은 DATEMODIFIED 값을 가지며 DateTime.MinValue를 startDate로 전달하더라도 쿼리가 여전히 모든 엔티티와 일치하지 않습니다.

가 나는 경우 - 문 앞에 중단 점을 설정하고 시도하고 무슨 일이 일어나고 있는지 확인하기 위해 Visual Studio를 조사 식 창을 사용 :

q.ToList()(0).DATEMODIFIED 'Returns the expected date 
startDate.Value    'Returns the expected date 
startDate.Value <= q.ToList()(0).DATEMODIFIED 'Returns True... 

을하지만 한 번이 = q.Where (술어) 부분 질문을 명중하면 , q.ToList()는 더 이상 항목을 반환하지 않습니다. 나는 혼란 스럽다.

+0

ObjectQuery.ToTraceString() (또는 SQL Profiler)을보고 여기에 param 값과 함께 게시하십시오. 를 선택 –

+0

1 C1, COMMENT_ID AS "Extent1".COMMENT_ID 코멘트 AS "Extent1".COMMENTS, SYS_GEN_FLAG AS "Extent1".SYS_GEN_FLAG, "Extent1".ITEM_ID ITEM_ID AS, "Extent1".MODIFIEDBY AS AS MODIFIEDBY, "Extent1".DATEMODIFIED DATEMODIFIED, COMPANY_ID AS "Extent1".COMPANY_ID, "Extent1".ORG_ID, ORG_ID AS "Extent1".SUBTAB_ID SUBTAB_ID AS, "Extent1".USER_ID USER_ID AS, "Extent1 AS .COMPANY_SECTION COMPANY_SECTION COMPANY_SECTION AIP.CO_COMMENT "Extent1" WHERE ("Extent1".COMPANY_ID = : p__linq__49) AND ("Extent1".DATEMODIFIED> = (CAST (: p__linq __53 AS TIMESTAMP (9)))) – echo

+0

매우 유용합니다. objectQuery.Parameters ("p__linq__53")의 값을 게시 할 수 있습니까? –

답변

2

업데이트 : 아차, 내가 LINQ와 엔티티로, 표현식 SQL로 번역하는 모든 WHERE 대신 사후 처리 디버깅 제안 사항은 아래 반드시 작동하지 않도록 code--에있는의 호출 것을 잊어 버렸습니다.

따라서 생성 된 SQL 문을 데이터베이스에 대해 실행하고 Entity Framework 공급자가 생성 한 SQL이 실제로 예상 한 데이터를 반환하는지 확인하는 것으로 시작합니다. 위의 @Craig Stuntz의 의견은 확실히 당신이 이것을 할 수 있도록 도움이 될 것입니다. 일단 매개 변수화 된 SQL을 가지고 있다면 코드에서 직접 (System.Data.OracleClient을 사용하여) 해당 SQL을 실행 해보고 실제로 해당 쿼리에서 결과를 얻는다는 것을 검증 할 수 있습니다. ObjectQuery.Parameters에서 얻은 것과 동일한 매개 변수 값을 주입해야합니다. 또는 자신의 매개 변수를 고수하고 선택한 Oracle 클라이언트 응용 프로그램에서 쿼리를 실행할 수 있습니다.

해당 SQL에서 결과를 얻지 못하면 devArt의 공급자가 쿼리를 잘못 작성하고있을 가능성이 있습니다.

가이 진단하는 LINQ - 객체-에 있지만 LINQ - 투 - 엔티티

몇 가지 아이디어를 문제 해결에 적용하기 때문에 당신이 여기 아래에 무엇을 무시할 수 있습니다 :

첫째,이 시도하여 윈도우 시계 :

q.Where(Function(c) startDate.Value <= c.DATEMODIFIED).Count() 

I는 0을 반환합니다이 있으리라 믿고있어,하지만 당신이 정말로 어떤 결과를 얻고 있지하고 있는지 확인하기 위해 다른 많은 변수를 제거 가치가있다. 다음,

Dim q As ObjectQuery(Of COMMENT) 
If startDate.HasValue Then 
    q = (From c In model.COMMENT Where startDate.Value <= c.DATEMODIFIED Select c) 
Else 
    q = (From c In model.COMMENT Select c) 
End If 

을이 작동하는 경우 :

다음, 내가 노력하겠다고은 LINQ 조금이 같은 두 개의 쿼리를 사용하려고 differently-- 대신 별도)합니다 (어디를 추가 쿼리 정의하는 것입니다 Where 절이 기존 LINQ 쿼리에 연결되는 방식에 문제가 있습니다. 아마도 DBMS의 엔터티 프레임 워크 공급자의 버그일까요?

여전히 작동하지 않는다면 진단을 위해 취할 다음 단계는 where 절 안의 코드가 호출되고 있는지 확인하고 해당 코드로 전달 된 값을 검사하는 것입니다. VB에서 인라인 중단 점을 설정하는 방법을 C#에서 할 수있는 것처럼 이해할 수는 없지만 람다를 별도의 함수로 쉽게 (일시적으로) 리팩터링하고 중단 점을 설정할 수 있습니다.이렇게 :

Sub Main() 
    Dim testDate As Date = New Date(2005, 1, 1) 
    Dim x = New List(Of Date?) 
    x.Add(New Date(2009, 1, 1)) 
    x.Add(New Date(2008, 1, 1)) 
    x.Add(New Date(2007, 1, 1)) 
    x.Add(New Date(2006, 1, 1)) 
    x.Add(New Date(2005, 1, 1)) 
    x.Add(New Date(2004, 1, 1)) 
    x.Add(New Date(2003, 1, 1)) 
    x.Add(New Date(2002, 1, 1)) 
    x.Add(New Date(2001, 1, 1)) 
    Dim y = From n In x Select n 
    y = y.Where(Function(val) test(val, testDate)) 
    Dim z = y.ToArray() 
End Sub 

Function test(ByVal date1 As Date, ByVal date2 As Date) As Boolean 
    test = date1 >= date2 
End Function 

비교 기능으로 전송되는 값을 확인하십시오. 유효합니까? 비교 결과에 따라 기대 한 결과가 반환됩니까?

+0

저스틴, 답장을 보내 주셔서 감사합니다. 첫 번째 제안을 시도했을 때 "람다 식 평가가 디버거에서 유효하지 않습니다"라고했습니다. 그러나 q.tolist(). Count()는 실제로 0을 반환합니다. 두 번째 제안에 대해 쿼리를 재정렬해도 아무런 차이가 없습니다. 마지막으로 "test()"함수를 정의하고 <= 비교로 바꾸면 Entity Framework에서 예외가 throw됩니다 (여기서는 약간 구두로) : System.NotSupportedException : LINQ to Entities가 'Test'메서드를 인식하지 못합니다. 메서드를 사용하고이 메서드를 저장소 식으로 변환 할 수 없습니다. – echo

+0

DBMS는 Oracle 10g이고 EF 공급자는 oracle의 DevArt dotConnect입니다. – echo