tutorial primary mvc framework first existing español define code c# ef-code-first foreign-keys entity-framework-5 ef-database-first

c# - primary - Modelado de asociaciones polimórficas base de datos primero frente a código primero



mvc entity framework español (1)

Personalmente me quedo con la Base de datos primero cuando uso EF en cualquier esquema que tenga este nivel de complejidad. He tenido problemas con esquemas complejos en lo que respecta al código primero. Tal vez las versiones más recientes sean un poco mejores, pero preocuparse por cómo intentar y codificar relaciones complejas parece menos sencillo que permitir que el motor lo genere por ti. Además, cuando una relación se complica, tiendo a evitar intentar generarla con EF y probar y usar procedimientos almacenados para solucionar más fácilmente los cuellos de botella en el rendimiento que pueden surgir.

Tenemos una base de datos en la que una tabla contiene registros que pueden ser secundarios a otras tablas. Tiene una clave externa "blanda" que consta de la identificación del propietario y un nombre de tabla. Este (anti) patrón se conoce como "asociaciones polimórficas". Sabemos que no es el mejor diseño de base de datos y lo cambiaremos a su debido tiempo, pero no en el futuro cercano. Déjame mostrarte un ejemplo simplificado:

Tanto el Event Person y el Product tienen registros en el comentario. Como ves, no hay restricciones FK duras.

En Entity Framework, es posible admitir este modelo mediante la clasificación de los Comment en EventComment etc., y permitir que Event tenga una colección EventComments , etc.

Las subclases y las asociaciones se agregan manualmente después de generar el modelo básico de la base de datos. OwnerCode es el discriminador en este modelo de TPH . Tenga en cuenta que Event , Person y Product son entidades completamente diferentes. No tiene sentido tener una clase base común para ellos.

Esta es la base de datos primero Nuestro modelo de la vida real funciona así, no hay problema.

DE ACUERDO. Ahora queremos pasar al código primero. Así que empecé a aplicar ingeniería inversa de la base de datos en un modelo de código primero (EF Power Tools) y continué creando las subclases y mapeando las asociaciones y la herencia. Intenté conectar al modelo en Linqpad. Fue entonces cuando empezaron los problemas.

Cuando se intenta ejecutar una consulta con este modelo, se lanza una InvalidOperationExeception

El componente de clave foránea ''OwnerId'' no es una propiedad declarada en el tipo ''EventComment''. Verifique que no se haya excluido explícitamente del modelo y que sea una propiedad primitiva válida.

Esto sucede cuando tengo asociaciones bidireccionales y OwnerId se asigna como una propiedad en el Comment . La asignación en mi clase EventMap ( EntityTypeConfiguration<Event> ) se ve así:

this.HasMany(x => x.Comments).WithRequired(c => c.Event) .HasForeignKey(c => c.OwnerId);

Así que traté de mapear la asociación sin OwnerId en el modelo:

this.HasMany(x => x.Comments).WithRequired().Map(m => m.MapKey("OwnerId"));

Esto lanza una MetaDataException

El esquema especificado no es válido. Errores: (10,6): error 0019: cada nombre de propiedad en un tipo debe ser único. El nombre de propiedad ''OwnerId'' ya estaba definido. (11,6): error 0019: cada nombre de propiedad en un tipo debe ser único. El nombre de propiedad ''OwnerId'' ya estaba definido.

Si elimino dos de las tres asociaciones de comentarios de entidades, está bien, pero por supuesto eso no es una cura.

Algunos detalles adicionales:

  • Es posible crear un modelo DbContext que funcione ("segundo código") a partir de edmx agregando un elemento del generador DbContext. (Esto sería una solución temporal por el momento).
  • Cuando exporto el modelo de código primero en funcionamiento (con una asociación) a edmx ( EdmxWriter ), la asociación parece estar en el modelo de almacenamiento, mientras que en el edmx original son parte del modelo conceptual.

Entonces, ¿cómo puedo crear este código de modelo primero? Creo que la clave es cómo indicar al código primero que mapee las asociaciones en el modelo conceptual, no en el modelo de almacenamiento.