.net - multiple - ¿Por qué usar LINQ Join en una relación simple de uno a muchos?
linq select many example c# (3)
Las uniones son probablemente más comunes para las personas que provienen de la mentalidad Relacional en lugar de la orientada a objetos. Si piensa en su espacio problemático desde una perspectiva orientada a objetos, es mucho más natural trabajar con relaciones en las que puede puntear a través de la navegación: Employee.Customers.Orders.OrderItems.OrderItem
que tratar con un montón de combinaciones. El documento técnico original de ADO.vNext hizo un buen trabajo al analizar las ventajas de usar el modelo y las asociaciones en lugar de unirse para tratar sus modelos conceptuales. Desafortunadamente, no puedo encontrar ese documento en este punto.
Para mí, las uniones se utilizan mejor cuando no tienes asociaciones naturales entre entidades. Por ejemplo, si está intentando unir elementos en claves no naturales (es decir, unirse en Customer.State
y Shipping.State
), en este caso debe usar la sintaxis de unión (o SelectMany
) en lugar de crear asociaciones entre sus entidades.
Una cosa a tener en cuenta es que la sintaxis de unión y el uso de asociaciones pueden causar diferencias en el tipo de combinaciones que genera el proveedor. Normalmente, una combinación se traduce en una combinación interna y excluye los elementos en los que no hay coincidencia en ambos lados de la combinación. Para realizar una combinación externa (izquierda), utilice la extensión DefaultIfEmpty
.
La navegación a través de las asociaciones en una relación 1-0 .. * por otro lado, normalmente se traduce en uniones externas correctas porque la colección secundaria podría estar legítimamente vacía y usted querría incluir al padre incluso si el niño no existiera. Usted usaría !Any()
para atrapar en los casos donde no hay registros secundarios.
He estado usando LINQ to SQL y Entity Framework durante algunos años y siempre he mapeado las relaciones de mi base de datos para generar las propiedades de navegación relevantes. Y siempre uso las propiedades de navegación.
¿Me estoy perdiendo de algo?
Si tengo una relación Category->Products
uno-muchos, usaría
var redProducts = context.Category.Single(c => c.Name = "red").Products;
Con frecuencia veo personas que realizan uniones manuales, en todo este sitio, en proyectos en línea y en otros sitios web.
var employer = from category in context.Categories
join product in context.Products
on category.CategoryId equals product.CategoryId
where category.Name == "red"
select product;
¿Entonces por qué? ¿Cuáles son los beneficios de usar esta sintaxis de unión?
Podría ser el resultado de portar el código antiguo a linq2sql.
Sin embargo, los dos fragmentos de código no son funcionalmente iguales.
Single
lanzará una excepción, mientras que join
produce una colección vacía en caso de que falte un registro.
Entonces, un código igual sin usar uniones sería:
from c in context.Categories where c.Name == "red" from p in c.Products select p;
o
context.Categories.Where(c=>c.Name == "red").SelectMany(c=>c.Products);
Sin embargo, @George tiene razón en que sus dos ejemplos son funcionalmente diferentes de una manera que no tiene nada que ver con la join
contra la no join
. Pero usted podría escribir tan fácilmente:
var redProducts = context.Category
.Where(c => c.Name == "red")
.SelectMany(c => c.Products);
... que es funcionalmente idéntico (pero superior a un POV de legibilidad y mantenibilidad) a su ejemplo de join
.