Domanda

Sto utilizzando Entity Framework, e ho un'entità COMMENTO. UN COMMENTO ha una proprietà DateModified, che è un Nullable Data. Sto cercando di costruire una query che filtrerà i commenti per data, in modo da creare un oggetto startDate, e procedere come segue:

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

Il problema è che q.toList () non restituisce alcun commento, anche se penso che dovrebbe. Tutti i commenti presenti nel database hanno valori DateModified, e anche se mi passa nel DateTime.MinValue come startDate, la query ancora non corrisponde a tutte le entità.

Ho impostato un punto di interruzione prima della Se-Economico e usato la di finestra di Visual Studio per provare e vedere cosa sta succedendo:

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

Ma una volta che una volta colpisce la q = D. Dove (predicato) parte, q.ToList () non restituisce tutte le voci. Sono perplesso.

È stato utile?

Soluzione

UPDATE: Ops, ho dimenticato che, con LINQ to Entities, tutti dove le espressioni sono tradotti in SQL chiamate invece di essere post-elaborate in modo code-- i suggerimenti di debug di seguito non sarà necessariamente lavoro.

Quindi, mi piacerebbe iniziare eseguendo la stessa istruzione SQL generata contro il vostro database e convalidare se l'SQL generato dal provider di Entity Framework è effettivamente restituendo i dati che ci si aspetta. Il commento di @ Craig Stuntz sopra è sicuramente sulla strada giusta qui per aiutarvi a fare questo. Una volta che hai la SQL con parametri, mi piacerebbe provare a eseguire che SQL direttamente dal codice (utilizzando System.Data.OracleClient) e la convalida che è effettivamente ottenere risultati indietro da quella query. Ricordarsi di iniettare gli stessi valori dei parametri che si ottiene da ObjectQuery.Parameters. In alternativa, si potrebbe attaccare i parametri in te stesso ed eseguire la query da Oracle applicazione client di scelta.

Se non si ottengono i risultati di che SQL, allora è possibile che fornitore di Devart sta costruendo la query in modo non corretto.

si può ignorare ciò che è al di sotto qui, in quanto si applica alla risoluzione dei problemi di LINQ to Objects, ma non LINQ to Entities

Alcune idee per diagnosticare questa:

Per prima cosa, provate questo nella vostra finestra di controllo:

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

Sto assumendo questo tornerà a zero, ma vale la pena l'eliminazione come molte altre variabili per assicurarsi che non sei veramente ottenere alcun risultato.

Poi, mi piacerebbe provare è quello di definire il vostro LINQ interrogare un po 'differently-- invece di aggiungere il Dove () a parte, provare a utilizzare due query, in questo modo:

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

Se questo funziona, allora c'è qualcosa che non va con il modo la clausola Where viene collegato al LINQ esistente query-- forse un bug nel provider di entità-quadro del DBMS?

Se questo ancora non funziona, il passo successivo mi piacerebbe prendere per diagnosticare sarebbe quello di verificare che il codice all'interno della clausola in cui viene chiamato, e controllando i valori passati in quel codice. Non riuscivo a capire come impostare i punti di interruzione intra-linea in VB come si può fare in C #, ma si può facilmente (temporaneamente) refactoring del lambda in una funzione separata e impostare il punto di interruzione lì. In questo modo:

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

Controllare i valori inviati nel vostro confronto function-- sono essi valide? Ha il confronto restituire ciò che ci si aspetta che?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top