objects homepage framework entityframework data entity-framework poco

entity-framework - homepage - entityframework reverse poco generator



Primero el código: asociaciones independientes vs. asociaciones de claves extranjeras? (4)

Tengo un debate mental conmigo mismo cada vez que comienzo a trabajar en un nuevo proyecto y estoy diseñando mis POCO. He visto muchos ejemplos de tutoriales / códigos que parecen favorecer las asociaciones de claves foráneas :

Asociación de claves extranjeras

public class Order { public int ID { get; set; } public int CustomerID { get; set; } // <-- Customer ID ... }

A diferencia de las asociaciones independientes :

Asociación independiente

public class Order { public int ID { get; set; } public Customer Customer { get; set; } // <-- Customer object ... }

He trabajado con NHibernate en el pasado y usé asociaciones independientes, que no solo sienten más OO, sino que también (con carga diferida) tienen la ventaja de brindarme acceso a todo el objeto del Cliente, en lugar de solo su ID. Esto me permite, por ejemplo, recuperar una instancia de pedido y luego hacer Order.Customer.FirstName sin tener que hacer una unión explícita, lo cual es extremadamente conveniente.

Entonces, para recapitular, mis preguntas son:

  1. ¿Hay desventajas significativas al usar asociaciones independientes? y...
  2. Si no hay ninguno, ¿cuál sería el motivo para usar asociaciones de claves foráneas?

La asociación independiente no funciona bien con AddOrUpdate que generalmente se usa en el método Seed . Cuando la referencia es un elemento existente, se volverá a insertar.

// Existing customer. var customer = new Customer { Id = 1, Name = "edit name" }; db.Set<Customer>().AddOrUpdate(customer); // New order. var order = new Order { Id = 1, Customer = customer }; db.Set<Order>().AddOrUpdate(order);

El resultado es que el cliente existente se volverá a insertar y el nuevo cliente (re-insertado) se asociará con un pedido nuevo.

A menos que usemos la asociación de clave externa y asignamos la identificación.

// Existing customer. var customer = new Customer { Id = 1, Name = "edit name" }; db.Set<Customer>().AddOrUpdate(customer); // New order. var order = new Order { Id = 1, CustomerId = customer.Id }; db.Set<Order>().AddOrUpdate(order);

Tenemos el comportamiento esperado, el cliente existente se asociará con un nuevo pedido.


Si desea aprovechar al máximo ORM, definitivamente utilizará la referencia de la entidad:

public class Order { public int ID { get; set; } public Customer Customer { get; set; } // <-- Customer object ... }

Una vez que genere un modelo de entidad desde una base de datos con FK, siempre generará referencias de entidad. Si no desea utilizarlos, debe modificar manualmente el archivo EDMX y agregar propiedades que representen FK. Al menos este fue el caso en Entity Framework v1 donde solo se permitieron asociaciones independientes.

Entity framework v4 ofrece un nuevo tipo de asociación llamada asociación de clave externa. La diferencia más obvia entre la asociación de clave externa e independiente es en clase de orden:

public class Order { public int ID { get; set; } public int CustomerId { get; set; } // <-- Customer ID public Customer Customer { get; set; } // <-- Customer object ... }

Como puede ver, tiene la propiedad FK y la referencia de la entidad. Hay más diferencias entre dos tipos de asociaciones:

Asociación independiente

  • Se representa como un objeto separado en ObjectStateManager . ¡Tiene su propio EntityState !
  • Cuando se crea una asociación, siempre se necesitan las entidades de ambos extremos de la asociación
  • Esta asociación se mapea de la misma manera que la entidad.

Asociación de claves extranjeras

  • No se representa como un objeto separado en ObjectStateManager . Debido a eso debes seguir algunas reglas especiales.
  • Cuando construyes una asociación, no necesitas los dos extremos de la asociación. Es suficiente tener la entidad hijo y PK de la entidad padre, pero el valor PK debe ser único. Por lo tanto, al usar la asociación de claves externas también debe asignar identificadores únicos temporales a las entidades recién generadas utilizadas en las relaciones.
  • Esta asociación no está mapeada, sino que define restricciones referenciales.

Si desea utilizar una asociación de clave externa, debe marcar Incluir columnas de clave externa en el modelo en el Asistente de modelo de datos de entidad.

Editar:

Descubrí que la diferencia entre estos dos tipos de asociaciones no es muy conocida, así que escribí un breve artículo sobre este tema con más detalles y mi propia opinión al respecto.


Usa ambos. Y haga que las referencias de su entidad sean virtuales para permitir la carga diferida. Me gusta esto:

public class Order { public int ID { get; set; } public int CustomerID { get; set; } public virtual Customer Customer { get; set; } // <-- Customer object ... }

Esto ahorra búsquedas innecesarias de BD, permite la carga diferida y le permite ver / configurar fácilmente la ID si sabe lo que quiere que sea. Tenga en cuenta que tener ambos no cambia la estructura de su tabla de ninguna manera.


Yo prefiero el enfoque de objetos para evitar búsquedas innecesarias. Los objetos de propiedad pueden rellenarse fácilmente cuando se llama a su método de fábrica para construir la entidad completa (utilizando un código de devolución de llamada simple para entidades anidadas). No hay desventajas que pueda ver, excepto el uso de memoria (pero podría almacenar en caché sus objetos, ¿no?). Entonces, todo lo que está haciendo es sustituir la pila por el montón y obtener un aumento en el rendimiento al no realizar búsquedas. Espero que esto tenga sentido.