2010-04-20 20 views
9

Questo funziona:Perché LINQ-to-Entites riconosce il mio metodo personalizzato?

Entities.WorkOrderSet.Where(MyCustomMethod); 

Questo non lo fa:

Entities.WorkOrderSet.Where(o => MyCustomMethod(o)); 

([Edit] Anche senza new, esso non funziona)

capisco perché il secondo non funziona - ma perché nel mondo fa il primo lavoro !? Non dovrei ottenere un "LINQ-to-Entities non riconosce il metodo ..." in fase di runtime, come con il secondo?

Per riferimento, ecco myCustomMethod

public bool MyCustomMethod(WorkOrder workOrder) 
{ 
    return !workOrder.WorkOrderNum.StartsWith("A", StringComparison.CurrentCultureIgnoreCase); 
} 

Utilizzando EF1, non EF4

+0

Quale eccezione si ottiene quando si tenta di eseguire il secondo? –

+0

Inoltre ... sei sicuro che EF non acquisirà solo l'intera tabella ed eseguirà la funzione localmente quando eseguirai il tuo primo tipo di shippet? Eseguire il profiler SQL e verificare quale query viene inviata al server? –

+0

Ottengo "LINQ-To-Entities non può riconoscere il metodo ..." - questo è il comportamento previsto, poiché i metodi personalizzati non possono essere tradotti in SQL. La solita soluzione è chiamare prima .ToList() ... ma per qualche ragione, sembra che funzioni senza! –

risposta

6

Prima funziona perché è un metodo di estensione ed è sta eseguendo il query come FUNC e quindi filtrando il tuo elenco see here. Quindi, in generale sarebbe gettato automaticamente il dove

Where(Func<WorkOrder, bool> 

In secondo luogo non si fa perché sta spingendo la sua dichiarazione in cui fino al db. Quando l'espressione lambda è valutato che si espande in questo modo:

Where(Expresion<Func<WorkOrder, bool>>) 

Ecco un buon article che spiega Expressions vs Funz

Here is another SO post that helps to explain the difference

[Edit (BlueRaja)]

Questa nuova modifica sembra essere corretta. Per chiarire: sembra che Func<WorkOrder, bool> sia implicitamente applicabile a Expression<Func<WorkOrder, bool>>, ma non viceversa.

Ci sono sovraccarichi di Where per entrambi i tipi. .Where(MyCustomMethod) chiama lo Func<WorkOrder, bool>, mentre .Where(o => MyCustomMethod(o)) chiama lo Expression<Func<WorkOrder, bool>>.

+1

Si prega di controllare di nuovo .. Potrebbe utilizzare una classe anonima, ma il suo metodo personalizzato riceverà comunque un oggetto WorkOrder come parametro, mentre il codice non verrà nemmeno compilato :) –

+0

Forse avrei dovuto elaborare (vedi modifica sopra): il codice viene compilato, ma non riesce in fase di esecuzione a causa di * "LINQ alle entità non riconosce il metodo ..." * Esempio: http://blog.dreamlabsolutions.com/post/2008/11/17/LINQ-Method- non può essere-tradotto-in-un-archivio-espressione.aspx Questo è previsto, ma il fatto che il primo funzioni è inaspettato! –

+0

@Nix guarda di nuovo: P nuovo {WorkOrder = o} è in effetti una classe anonima ... Inside .Where (o => ...) o è la classe anonima .. Mentre o.WorkOrder è di tipo WorkOrder .. nel qual caso il parametro che è passato nella sua funzione è del tipo corretto! –

1

Proprio la formazione di questo come una "risposta" qui, al posto di un commento ..

Penso che questa sia una nuova funzionalità di .NET 4, dove il quadro si rende conto che questa funzione non può essere tradotto in SQL, ma può essere facilmente elaborato in memoria. Così si ottiene l'intero set di dati alla macchina locale e continua l'elaborazione delle query ..

La cosa è il vostro primo frammento, quando tradotto in un albero di espressione, sarebbe direttamente dire che si esegue un metodo esterno, mentre il secondo frammento è non così "diretto". Suppongo che questo sia il motivo per cui nel primo caso L2E può facilmente capire cosa sta succedendo, e decidere cosa fare, mentre nel secondo caso "pensa" è meglio inviare un'eccezione e lasciare che gli sviluppatori si gratta ancora di più^_^

+0

Utilizzando EF1, che è .Net 3.5 –

+0

forse è una cosa da EF1 a L2S 1 allora? O forse è una funzionalità che è stata lì da qualche tempo? Qualunque cosa sia, la migliore spiegazione che posso fornire è che il framework sta cercando di essere intelligente, in base all'albero delle espressioni in cui viene compilata la query in :) –

Problemi correlati