2015-12-24 3 views
8

Quando aggiungo proprietà extra a una classe generata automaticamente da EF utilizzando una classe parziale aggiuntiva, queste proprietà non vengono compilate o riempite quando si eseguono query sul database.Le proprietà extra di Entity Framework non vengono popolate da DbContext.Database.SqlQuery

Esempio:

persona di classe generata automaticamente:

public partial class Person 
{ 
    public string Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

mia classe parziale

public partial class Person 
{ 
    public string DisplayName{ get; set; } 
} 

Quando faccio la seguente query:

"SELECT *, (FirstName + LastName) AS DisplayName FROM [Person]" 

e l'uso

DbContext.Database.SqlQuery(typePerson, SQL, null) 

l'Id, Nome e cognome sono popolate, ma non il DisplayName.

Tuttavia quando creo una nuova classe chiamata myPerson

public partial class MyPerson 
{ 
    public string Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string DisplayName{ get; set; } 
} 

e si esegue la stessa query con il tipo di myPerson il DisplayName è popolata pure.

Qualcuno può spiegare questo o dirmi come posso risolvere questo problema, quindi posso utilizzare Partials invece di dover creare nuove classi/tipi.

Scarica un esempio: https://www.dropbox.com/s/dayrv0jzuoju9q3/StackOverflow_EF_ExtraProperties.zip?dl=0

UPDATE 2015/12/28: Durante la lettura attraverso altri StackOverflow e forum CodeProject ho trovato un altro modo per farlo funzionare:

1) Utilizzando TypeBuilder (http://www.codeproject.com/Articles/206416/Use-dynamic-type-in-Entity-Framework-SqlQuery) ma a causa di tutti i tipi di dipendenze del progetto ho avuto problemi nel trovare i tipi già creati e non far esplodere la memoria;

2) Opzione migliore finora: utilizzo dell'ereditarietà.

Quando creo un'altra classe con solo queste righe:

class Person_Reflect : Person { } 

posso utilizzare il seguente codice (ignorerà il mapping nel file e l'uso di riflessione EDMX:

List<EF.Person> listPerson = dbEntities.Database.SqlQuery<EF.Person_Reflect>(sql, new object[] { }).ToList<EF.Person>(); 
+3

Sei certo che la seconda classe parziale di 'Person' è nel namespace giusto? –

+0

E nessuna eccezione dal momento che hai cambiato il modello? – dotctor

+0

Vedete DisplayName come una proprietà senza valore? –

risposta

0

prova remove il *

@" 
SELECT 
    Id 
    ,FirstName 
    ,LastName 
    ,(FirstName + ' ' + LastName) AS DisplayName 
FROM [Person]" 

In alternativa si potrebbe fare questo è il codice ... e poi non si farebbe necessità di includere nel vostro SQL prime

public string DisplayName { get { return FirstName+ " " +LastName ; } } 
+0

Lasciando fuori il * non funziona, lo rende persino peggiore; se dimentico una colonna, l'applicazione termina con l'eccezione: Il lettore di dati non è compatibile con l''Application.Person' specificato. Un membro del tipo "COLUMNNAME" non ha una colonna corrispondente nel lettore di dati con lo stesso nome. Hai perfettamente ragione, la tua soluzione di codifica risolve questo esempio, ma ho una query dinamica che può essere arricchita in runtime per creare una moltitudine di scelte dell'utente finale su come visualizzare/formattare i risultati. Quindi ho solo un'opzione di visualizzazione: usare le valute o creare query dinamiche. –

+0

dovrebbe funzionare ... la colonna deve essere la stessa CASE e tipo di dati. Ho fatto qualcosa di simile a me stesso, quindi so che funziona ... Si prega di controllare doppia caso e tipi – Seabizkit

+0

Caro Seabizkit. Ho caricato un esempio di prova in cui non riesco a far funzionare correttamente quello che hai realizzato. Il collegamento all'esempio completo è: https://www.dropbox.com/s/dayrv0jzuoju9q3/StackOverflow_EF_ExtraProperties.zip?dl=0 –

1

opzione migliore finora senza dover codice molto eo di fare la revisione del codice molto quando si verificano modifiche al database è quello di usare l'ereditarietà.

Quando creo un'altra classe con un solo questa linea:

class Person_Reflect : Person { } 

posso utilizzare il seguente codice (ignorerà il mapping nel file e l'uso di riflessione EDMX):

List<EF.Person> listPerson = dbEntities.Database.SqlQuery<EF.Person_Reflect>(sql, new object[] { }).ToList<EF.Person>();