2012-04-13 21 views
12

Ho cercato un argomento simile alla mia domanda su Internet negli ultimi giorni. Alla fine ho fatto ricorso a questa domanda io stesso.Mappatura dei risultati stored procedure Entity

Utilizzo della metodologia code-first e EF 4.3.1 Ho creato una classe di contesto, classi di entità e classi per memorizzare l'output della stored procedure. La classe di contesto ha metodi che eseguono determinate stored procedure utilizzando SqlQuery<T>.

Esempio:

public IEnumerable<Results> GetData(int id) 
{ 
    var parameters = new SqlParameter[] { new SqlParameter("@id", id) }; 
    var result = this.Database.SqlQuery<Result>("Exec dbo.sproc_GetData @id", parameters); 
    var data= result.ToList<Result>(); 

    return data; 
} 

Come sto tracciando il debug di miei dati ritorna, e dei dati viene associato a proprietà con un nome corrispondente. Tuttavia, nell'output c'è una colonna con un "/" nel nome (esempio: Info/Data). Ovviamente non posso nominare una proprietà del genere così ho pensato che avrei potuto mappare l'output utilizzando l'attributo di colonna ([Column("Info/Data")]):

[Column("Info/Data")] 
public string InfoData 
{ 
    get { return infoData; } 
    set { infoData= value; } 
} 

Ho anche provato ad utilizzare l'operatore di Verbatim ([Column(@"Info/Data")]), avvolgendo il testo con [] ([Column("[Info/Data]")]) e ho provato entrambi ([Column(@"[Info/Data]")]). Quando passo il codice vedo che le proprietà con i nomi delle colonne corrispondenti sono assegnate, ma le proprietà con l'attributo della colonna vengono ignorate e ignorate durante l'assegnazione.

Ho anche provato fluent-api per ogni colonna per l'entità.

modelBuilder.ComplexType<Result>().Property(d => d.InfoData).HasColumnName("Info/Data"); 

ma che getta la seguente eccezione:

Il lettore di dati è incompatibile con il specificata 'NameSpace.Result'. Un membro del tipo, "InfoData", non ha una colonna corrispondente nel lettore di dati con lo stesso nome.

Nel mio progetto NameSpace.Result è una classe (nome cambiato per sicurezza) e InfoDatais è la proprietà che provo a tracciare utilizzando fluente-API (la colonna SQL corrispondente ha una/in esso; es: Info/Dati) .

Qualcuno si è imbattuto in questo problema?

Se il mio problema non è chiaro o è stato chiesto prima di farmi sapere.

+7

Mi chiedo che tipo di persone chiamino Classi/tabelle di database con "/" carattere. –

+0

Questo fa due di noi. Non ho scritto il proc. Mi è stato detto di usare i dati. È stato molto sconvolgente vedere accadere l'aliasing. –

+0

Esiste la possibilità di creare wrapper SP con nomi di colonne normali nel risultato? – vittore

risposta

3

Mi rendo conto che questa è una vecchia domanda ora, ma poiché è stata accolta dalla recente risposta dell'OP, forse c'è ancora interesse in essa.

Se si è bloccati con quel processo memorizzato così com'è e si stanno restituendo i nomi di colonna incompatibili con EF, visto che si sta passando in SQL per chiamare proc direct con SqlQuery, è possibile utilizzare il metodo INSERT-EXEC per fare qualcosa come dichiarare una variabile di tabella (con nomi di colonne più compatibili), INSERT-EXEC il proc memorizzato nella variabile di tabella, quindi selezionare dalla variabile di tabella come set di risultati?

Sarebbe un SQL prolisso da passare e quindi la mia non è una soluzione gradevole, ma come un esercizio mentale per vedere se questo è un modo per aggirare il problema che pensavo di offrire.

Bel articolo qui su questo tipo di problema: http://www.sommarskog.se/share_data.html - la maggior parte dei metodi non sono utili in quanto non è possibile modificare il processo memorizzato (e presumibilmente non si ha accesso a nulla alla struttura del database o si apportano modifiche ad esso affatto?), ma il metodo INSERT-EXEC si apre come soluzione possibile senza la necessità di modificare nulla nel livello db ...

+0

Ho completamente dimenticato di Insert-Exec come ho letto solo su di esso e mai effettivamente utilizzato. È una soluzione molto migliore rispetto all'utilizzo di OPENROWSET come ho fatto nella mia risposta. Questa è certamente una soluzione possibile in quanto ti consente di mascherare i nomi delle colonne mal formati. –

0

Potrebbe non essere possibile fare ciò che vuoi. Quando si utilizza SQL raw, la porzione di mappatura di EF viene ignorata.

How to use Entity Framework to map results of a stored procedure to entity with differently named parameters

Stessa cosa con ExecuteStoreQuery http://social.msdn.microsoft.com/Forums/pl/adonetefx/thread/d524b005-12a4-4300-a974-1e0582de876b

È possibile utilizzare l'ObjectQuery per ottenere un elenco di oggetti DBDataRecord. Quindi utilizzare la funzione "Seleziona" di Linq per mappare i risultati sul tipo di oggetto. Se si esegue il wrapping di tale associazione in una funzione di estensione che accetta un oggetto IEnumerable e restituisce un oggetto IEnumberable.

Return Custom Object <List T> from Entity framework and assign to Object Data Source

+0

Ho finito per lasciare il progetto code-first e sono andato con il designer in questa istanza. Rimarrà in questo modo fino a quando il supporto alla mappatura non arriverà alle chiamate alle stored procedure. Grazie –

0

Andando avanti e pensare a questo problema uno dei più semplici (potenzialmente le soluzioni non puliti o migliori) è quello di avvolgere l'intero set di risultati in una nuova procedura. Naturalmente se hai la possibilità di modificare la procedura senza rompere nulla è la soluzione migliore.Tuttavia, se non è possibile modificare l'output, una soluzione è utilizzare OPENROWSET (Guarda la risposta di Aaron) per acquisire l'output della procedura in una tabella e selezionare ogni colonna con un nuovo alias che funzioni e aderisce ai principi di programmazione più puliti.

Spero che questo aiuti chiunque in futuro.

NOTA:
non ho controllato se la nuova versione di EF ha risolto questo problema.

Problemi correlati