Come posso utilizzare un metodo personalizzato in una clausola di selezione LINQ-to-SQL?

c# expression-trees linq-to-sql

Domanda

Mi piacerebbe fare qualcosa di simile a ciò che è descritto in questo articolo . Tuttavia, l'articolo è del 2006 e richiede metodi di estensione scritti dall'autore. Spero che ci sia qualcosa di più integrato a questo punto.

L'intento qui è quello di salvare un metodo che contenga solo operazioni traducibili in T-SQL e utilizzarlo per assegnare proprietà specifiche in un'istruzione select LINQ-to-SQL. Se c'è un modo radicalmente diverso di fare ciò che ho tentato, allora è anche una risposta valida.

Come lo faccio?


Quello che ho provato

Ho una query simile a questa:

var theData = (
    from inv in dc.Inventory
    where inv.IsDeleted == false
    join data in cdc.InventoryDatas
    on inv.InvKey equals data.ReInvKey
    where data.ReColKey == colKey
    select new MyClass {
        SerialNumber = inv.SerialNumber,
        Data = InventoryData.DataExpression( data ),
        Name = inv.Name,
    }
);

Dove InventoryData.DataExpression è definito come tale:

public static Expression<Func<InventoryData, string>> DataExpression = (
    d => d.TextData != null ? d.TextData 
        : d.IntegerData != null ? d.IntegerData.ToString() 
        : d.DecimalData != null ? d.DecimalData.ToString() 
        : d.DateData != null ? d.DateData.ToString() 
        : d.BooleanData != null ? d.BooleanData.ToString()
        : null
);

Ma non è giusto. Come posso fare questo lavoro?

Risposta popolare

Funziona perfettamente quando si selezionano solo dati da una tabella e quando non combino altre espressioni nella parte destra dell'istruzione di assegnazione per la stessa proprietà:

Data = InventoryData.DataExpression.Compile()( data )

come fanno

select InventoryData.CompiledDataExpression( data )

e

select data.GetData()

dove CompiledDataExpression è definito come

public static Func<InventoryData, string> CompiledDataExpression 
    = InventoryData.DataExpression.Compile();

e GetData è definito come

public string GetData() {
    // execute the compiled delegete on this InventoryData
    var ret = InventoryData.CompiledDataExpression( this );

    return ret;
}

Tuttavia, il delegato non è in realtà compilato per T-SQL. Invece, vengono trascinati interi oggetti del tipo associato alla tabella, quindi il delegato viene eseguito su di essi localmente.

Viene visualizzato un errore quando provo la query completa, che si aggiunge ad altre tabelle e assegna il delegato a una sola delle diverse proprietà, alcune delle quali estraggono i dati dalle altre tabelle.



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché