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 tutoriales / ejemplos de código que parecen favorecer las asociaciones de claves externas :
Asociación de clave externa
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 se sienten más OO, sino que también (con carga diferida) tienen la ventaja de darme acceso a todo el objeto Cliente, en lugar de solo su ID. Esto me permite, por ejemplo, recuperar una instancia de Order y luego hacerlo Order.Customer.FirstName
sin tener que hacer una unión explícitamente, lo cual es extremadamente conveniente.
Entonces, para recapitular, mis preguntas son:
- ¿Existe alguna desventaja significativa en el uso de asociaciones independientes? y...
- Si no hay ninguna, ¿cuál sería la razón para utilizar asociaciones de claves externas?
fuente
Utilice ambos. Y haga que sus referencias de entidad sean virtuales para permitir la carga diferida. Me gusta esto:
Esto ahorra búsquedas de bases de datos innecesarias, 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.
fuente
La asociación independiente no funciona bien con la
AddOrUpdate
que se usa generalmente en elSeed
método. Cuando la referencia sea un elemento existente, se volverá a insertar.El resultado es que el cliente existente se volverá a insertar y el nuevo cliente (se volverá a insertar) se asociará con un nuevo pedido.
A menos que usemos la asociación de clave externa y asignemos la identificación.
Tenemos el comportamiento esperado, el cliente existente se asociará con un nuevo pedido.
fuente
var order = new Order { Id = 1, Customer = db.Customers.Find(1) };
O puede usar el método Seleccionar para cargar el cliente desde el contexto de la base de datos. Esto funciona con asociación independiente.Prefiero el enfoque de objetos para evitar búsquedas innecesarias. Los objetos de propiedad se pueden completar con la misma facilidad cuando llama a su método de fábrica para construir la entidad completa (usando un código de devolución de llamada simple para entidades anidadas). No hay desventajas que pueda ver, excepto por el uso de memoria (pero almacenaría en caché sus objetos, ¿verdad?). Por lo tanto, todo lo que está haciendo es sustituir la pila por el montón y obtener una ganancia de rendimiento al no realizar búsquedas. Espero que esto tenga sentido.
fuente