2011-02-23 12 views
7

Tengo un modelo simple con una entidad "BaseEntity" y una entidad "Fund" derivada. Cuando trato de insertar un nuevo fondo:Entity Framework 4: problema de herencia Tabla por tipo en la inserción

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(); 

me sale el siguiente error:

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

Parece que el ID asignado a la entidad fondo no se inserta en la tabla BaseEntity. Por qué no?

Hice esto "modelo primero". Si primero diseño la base de datos y creo el modelo a partir de ella, todo funciona bien ... ¡Pero primero necesito el modelo!

enter image description here

también ... por qué no hay un ObjectSet para "Funds" en mi DataContext (es decir, container.Funds)? ¡Gracias de antemano por tu ayuda!

+0

¿Qué es 'HybridModelContainer'? Publique una captura de pantalla de los detalles del mapeo de su entidad 'Fund'. –

+0

Ese es solo el nombre del DataContext. – SolarX

+0

@SolarX: ¿Podría publicar la captura de pantalla que mencioné? –

Respuesta

9

Solo puedo responder a la segunda parte de su pregunta: "Además ... ¿por qué no hay un ObjectSet para" Fondos "en mi DataContext (es decir, contenedor.Fundidos)?"

Es normal que ObjectContext solo tenga un ObjectSet de la clase base en su jerarquía de clases. Realmente no hay necesidad de un ObjectSet de las clases derivadas. Para agregar y eliminar objetos derivados a/desde ObjectContext, puede usar los métodos AddObject y DeleteObject de ObjectSet<BaseEntity>/BaseEntities, como ya hizo en su ejemplo.

Para consultar objetos derivados, puede aprovechar el método OfType del ObjectSet. Se devuelve un ObjectQuery del tipo derivado donde se puede construir otras preguntas sobre:.

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

(La primera parte de su pregunta suena como un error de asignación entre el almacenamiento y el modelo conceptual que podría tener una mejor CSi podría mostrar las partes pertinentes de su archivo edmx)

Editar:. Posible solución a la primera parte de la pregunta:

he creado tu ejemplo con el modelo, primero en VS2010 y podía reproducir su problema. El problema parece estar relacionado con el hecho de que la clave principal en su modelo no es un Int32 sino un Guid. Cuando agrega una nueva Entidad al Modelo, el diseñador siempre propone un Int32 como clave principal con StoreGeneratedPattern establecido en Identity.

Si cambia ahora el tipo de la llave en el diseñador modelo desde Int32 a Guid pero deja el StoreGeneratedPattern sin cambios siendo Identity, el DDL crea una base de datos en SQL Server con Id conjunto para escribir uniqueidentifier pero Identidad especificación para esa columna es "No".

Entonces, cuando EF envía un comando INSERT al DB, "piensa" desde la definición del modelo que el primario se autogenerará en el DB y no envía el Guid al DB que usted asignó en el código. Pero el DB no crea la clave, lo que da como resultado un valor NULL para la clave. De ahí el error que obtenemos.

Solución: Situado en el modelo de la propiedad Id de BaseEntityStoreGeneratedPattern a None. Para mí funcionó entonces. Por supuesto, usted es responsable de asignar siempre un Guid al Id antes de agregar un nuevo objeto al ObjectSet, pero eso parece ser lo que quiere de todos modos.

+0

Gracias. Intenté lo mismo con una primera base de datos y todo funciona (después de eliminar las relaciones y configurar la herencia en el modelo). Simplemente no puedo hacer que esto funcione con el enfoque de "modelo primero". Pero queremos ir primero al modelo. ¿Alguna idea? – SolarX

+0

@SolarX: Tal vez encontré la solución: vea la edición en mi respuesta anterior. – Slauma

+0

Probaré esto tan pronto como sepa de mis reuniones ... Esperaba que fuera un problema con Guid. Es curioso que no pude encontrar nada sobre eso en la web. Muchas gracias por tu ayuda !! – SolarX

Cuestiones relacionadas