c# - framework - join varias tablas linq



Conversión a un tipo derivado en una consulta LINQ to Entities con herencia de tabla por jerarquía (4)

Tengo un LINQ para el modelo de entidades con herencia de tabla por jerarquía. Tengo una consulta sobre el tipo base y quiero hacer una lógica específica dependiente del tipo. Por ejemplo:

IQueryable<BaseType> base = ...

// this works fine
var result = base.Select(b => b is DerivedType1 ? 1 : 2).ToList();

// this doesn't compile to SQL
var result2 = base.Select(b => b is DerivedType1 ? ((DerivedType1)b).DerivedProperty : null).ToList();

¿Hay alguna manera de hacer algo como esto sin procesar IQueryables de cada tipo derivado por separado:

// I'd rather not do this:
var resultA = base.OfType<DerivedType1>().Select(d => d.DerivedProperty);
var resultB = base.OfType<DerivedType2>().Select(d => default(int?));
var result = resultA.Concat(resultB).ToList();

https://src-bin.com


Answer #1

Intenta esto, nunca he hecho nada con la necesidad de hacer este tipo de esto, pero debería hacerlo. Además, si usa base , en primer lugar no porque es una palabra clave, pero si debe hacerlo, use @base la @ delante del nombre denota que no se usa como palabra clave.

var resultA = base.Select(aVar =>
                            (aVar is DerivedType1) ?
                                (DerivedType)(((DerivedType1)aVar).DerivedProperty)
                                :
                                (DerivedType)(default(int?))
                        ).ToList();

Answer #2

La conversión directa a un tipo de entidad como (DerivedType1)b no es compatible con LINQ-to-Entities pero el operador as ( b as DerivedType1 ) sí lo es, por lo que puede intentar:

var result2 = base
    .Select(b => b is DerivedType1
        ? (b as DerivedType1).DerivedProperty
        : null)
    .ToList();

Answer #3

Puede usar EntityFramework.Extended para mejorar el rendimiento de la consulta en lugar de hacer 2 viajes de ida y vuelta a DB.

var resultA = base.OfType<DerivedType1>().Select(d => d.DerivedProperty).Future();
var resultB = base.OfType<DerivedType2>().Select(d => default(int?)).Future();
var result = resultA.Concat(resultB).ToList();

En este caso solo se ejecuta un viaje de ida y vuelta a bd. Este marco es muy útil para muchas otras cosas int EF


Answer #4
OfType<DerivedType1>() 

devolverá un IEnumerable, si es posible, intente cambiar a base-tipo a IEnumerable en lugar de IQueryable, puede que tenga algunas restricciones de SQL al usar IQueryable.

Eso es, por supuesto, si en realidad no estás preguntando una base de datos?





linq-to-entities