85 votos

Primer código: asociaciones Independientes vs. asociaciones de clave externa?

Tengo un mental debate conmigo mismo cada vez que empiezo a trabajar en un nuevo proyecto y estoy diseñando mis POCOs. He visto muchos tutoriales/ejemplos de código que parecen favorecer a las asociaciones de clave externa:

Asociación de clave externa

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

Como contraposición a 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 utilizada asociaciones independientes, que no sólo se sienten más OO, pero también (con carga diferida) tienen la ventaja de que me de acceso a la totalidad del objeto del Cliente, en lugar de su ID. Esto me permite, por ejemplo, recuperar una Orden de la instancia y, a continuación, haga Order.Customer.FirstName sin tener que hacer una combinación de forma explícita, lo cual es muy conveniente.

Así que para recapitular, mis preguntas son:

  1. ¿Hay desventajas significativas en el uso de asociaciones independientes? y...
  2. Si no hay ninguna, lo que sería la razón de la utilización de las asociaciones de clave externa?

92voto

Ladislav Mrnka Puntos 218632

Si usted desea tomar ventaja completa de ORM definitivamente se utiliza la referencia de Entidad:

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

Una vez que generar un modelo de entidad de una base de datos con FKs será siempre generar referencias de entidad. Si usted no quiere hacer uso de ellos debe modificar manualmente el archivo EDMX y agregar propiedades que representan FKs. Al menos este era el caso en el Marco de la Entidad v1 donde sólo asociaciones Independientes.

Entity framework v4 ofrece un nuevo tipo de asociación que se llama asociación de clave externa. La diferencia más obvia entre el independiente y la asociación de clave externa es en el Orden de la clase:

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

Como puedes ver tienes tanto FK propiedad y la entidad de referencia. Hay más diferencias entre los dos tipos de asociaciones:

Asociación independiente

  • Es representado como objeto independiente en ObjectStateManager. Tiene su propia EntityState!
  • Cuando la asociación para la construcción siempre se necesita entitites desde ambos extremos de la asociación
  • Esta asociación se asigna de la misma manera como entidad.

Asociación de clave externa

  • No es representado como objeto independiente en ObjectStateManager. Debido a que usted debe seguir algunas reglas especiales.
  • Cuando la asociación para la construcción no necesita a ambos extremos de la asociación. Es suficiente para tener el hijo de la entidad y PK de la entidad matriz, pero PK valor debe ser único. Así que cuando se utiliza claves externas de la asociación también se le debe asignar temporal de Identificadores únicos para recién generado entidades utilizadas en las relaciones.
  • Esta asociación no está asignado sino que se define límites referenciales.

Si desea usar la clave externa de la asociación deberá marcar Incluir columnas de clave externa en el modelo en el Asistente para Entity Data Model.

Edición:

He encontrado que la diferencia entre estos dos tipos de asociaciones no es muy conocido así que escribí un breve artículo que cubre esto con más detalles y mi propia opinión acerca de esto.

26voto

Seth Paulson Puntos 468

El uso de ambos. Y hacer que sus referencias de entidad virtual para permitir la carga diferida. Como esto:

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

De esta forma se evita innecesarios DB búsquedas, permite la carga perezosa, y le permite fácilmente ver/establecer el ID si usted sabe lo que usted desea que sea. Tenga en cuenta que tener tanto no cambia la estructura de la tabla de ninguna manera.

6voto

Yuliam Chandra Puntos 7324

Asociación independiente que no funciona bien con AddOrUpdate que se utiliza generalmente en Seed método. Cuando la referencia es un elemento existente, se vuelve 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 un cliente existente, se vuelve a insertar y de nuevo (re-insertado) el cliente será asociada con la nueva orden.


A menos que el uso de la clave externa de la asociación y asignar el identificador.

 // 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, cliente existente será asociada con la nueva orden.

3voto

Carnotaurus Puntos 1861

Yo favorecen el objeto de enfoque para evitar búsquedas innecesarias. La propiedad de los objetos pueden ser tan fácilmente se rellena cuando se llama a su método de fábrica para construir el conjunto de la entidad (mediante la simple código de devolución de llamada para anidadas entidades). No hay ninguna desventajas que puedo ver, excepto para el uso de la memoria (pero en la caché los objetos de la derecha?). Así que, todo lo que están haciendo es sustituir la pila del montón y hacer una ganancia de rendimiento de la no realización de las búsquedas. Espero que esto tiene sentido.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X