2011-02-23 15 views
7

Ho un modello semplice con "BaseEntity" e un'entità "Fondo" derivata. Quando provo ad inserire un nuovo fondo:Entity Framework 4: problema ereditari di tipo Tabella per tipo sull'inserimento

HybridModelContainer container = new HybridModelContainer(); 

//Create new Fund 
Fund fund = new Fund(); 
fund.Id = Guid.NewGuid(); 
fund.DateCreated = DateTime.Now; 
fund.Name = "Fund 1"; 
fund.Number = 1; 
container.BaseEntities.AddObject(fund); 

container.SaveChanges(); 

ottengo il seguente errore:

"Cannot insert the value NULL into column 'Id', table 'HybridData.dbo.BaseEntities'; column does not allow nulls. INSERT fails.
The statement has been terminated."

Sembra che l'ID assegnato alla società veicolo non è inserita nella tabella BaseEntity. Perchè no?

Ho fatto questo "primo modello". Se progetto il database per primo e ne creo il modello, tutto funziona bene ... Ma prima ho bisogno del modello!

enter image description here

anche ... Perché non c'è un ObjectSet per "Funds" nel mio DataContext (vale a dire, container.Funds)? Grazie in anticipo per il vostro aiuto!

+0

Che cos'è "HybridModelContainer'? Pubblica uno screenshot dei dettagli di mappatura per la tua entità 'Fondo'. –

+0

Questo è solo il nome di DataContext. – SolarX

+0

@SolarX: Potresti per favore pubblicare lo screenshot che ho menzionato? –

risposta

9

Posso solo rispondere per la seconda parte della tua domanda: "Inoltre ... perché non c'è un ObjectSet per" Fondi "nel mio DataContext (cioè, container.Funds)?"

È normale che ObjectContext abbia solo un ObjectSet della classe base nella gerarchia di classi. Non c'è davvero bisogno di un ObjectSet delle classi derivate. Per aggiungere ed eliminare oggetti derivati ​​a/da ObjectContext, è sufficiente utilizzare i metodi AddObject e di ObjectSet<BaseEntity>/BaseEntities come già fatto nell'esempio.

Per eseguire query sugli oggetti derivati ​​è possibile utilizzare il metodo OfType di ObjectSet. Esso restituisce un ObjectQuery del tipo derivato dove si può costruire ulteriori domande su:.

ObjectQuery<Fund> query = container.BaseEntities.OfType<Fund>(); 

(La prima parte della tua domanda suona come un errore di mapping tra lo stoccaggio e il modello concettuale che potrebbe avere una migliore cif voi potrebbe mostrare le parti rilevanti del file edmx)

Edit:. Possibile soluzione alla prima parte della domanda:

ho creato il vostro esempio con il modello-prima in VS2010 e ho potuto riprodurre la vostra problema. Il problema sembra essere correlato al fatto che la chiave primaria del modello non è uno Int32 ma uno Guid. Quando si aggiunge una nuova entità al modello, il progettista propone sempre una chiave primaria Int32 con StoreGeneratedPattern impostata su Identity.

Se si cambia ora il tipo di chiave nel modello progettista Int32-Guid ma lascia la StoreGeneratedPattern immutata essendo Identity, il DDL crea un database in SQL Server con Id set di digitare uniqueidentifier ma identità specifica per quella colonna è "No".

Quindi, quando EF invia un comando INSERT al DB, "pensa" dalla definizione del modello, il primario verrà generato automaticamente nel DB e non invia il Guid al DB che è stato assegnato nel codice. Ma il DB non crea la chiave, risultando in un valore NULL per la chiave. Da qui l'errore che otteniamo.

Soluzione: impostare nel modello di progettazione per la proprietà Id di BaseEntity da StoreGeneratedPattern a None. Per me ha funzionato allora. Naturalmente, si è quindi responsabili di assegnare sempre una guida a Id prima di aggiungere un nuovo oggetto all'ObjectSet, ma sembra essere quello che si desidera comunque.

+0

Grazie. Ho provato la stessa cosa con un primo approccio al database e tutto funziona (dopo aver rimosso le relazioni e impostato l'ereditarietà nel modello). Non riesco proprio a farlo funzionare con l'approccio "primo modello". Ma vogliamo andare prima al modello. Qualche idea? – SolarX

+0

@SolarX: Forse ho trovato la soluzione: vedere la modifica nella mia risposta sopra. – Slauma

+0

Lo proverò appena ricevo le mie riunioni ... mi aspettavo che fosse un problema con Guid. È curioso di non aver trovato nulla su questo nel web. Grazie mille per il vostro aiuto !! – SolarX

Problemi correlati