5

Tengo una clase base y dos clases derivadas.Entity Framework no consulta las clases derivadas - Error en DbOfTypeExpression

Cada una de las clases derivadas implementa el mismo tipo que una propiedad; la única diferencia es el nombre de la propiedad.

Tristemente no tengo mucha influencia en el diseño de clase -> se han generado desde un archivo wsdl.

Luego tengo una propiedad en BaseType para encapsular la propiedad común. El plan era utilizar esta propiedad en mis puntos de vista web, etc

he utilizado el famoso "Fruit-Ejemplo" para demostrar el problema:

public class FruitBase 
    { 
     public virtual int ID { get; set; } 


     // 
     // The plan is to use this property in mvc view 
     // 
     [NotMapped] 
     public virtual FruitnessFactor Fruitness 
     { 
      get 
      { 
       if (this.GetType().BaseType == typeof(Apple)) 
        return ((Apple)this).AppleFruitness; 
       else if (this.GetType().BaseType == typeof(Orange)) 
        return ((Orange)this).OrangeFruitness; 
       else 
        return null; 
      } 
     } 
    } 

public class FruitnessFactor { } 

En mi controlador MVC, la siguiente consulta funciona absolutamente bien :

return View(context.FruitEntities 
          .OfType<Apple>().Include(a =>a.AppleFruitness) 
          .ToList()); 

Pero éste no:

return View(context.FruitEntities 
            .OfType<Apple>().Include(a =>a.AppleFruitness) 
            .OfType<Orange>().Include(o => o.OrangeFruitness) 
            .ToList()); 

El mensaje de error que consigo es :

DbOfTypeExpression requiere un argumento de expresión con un tipo de resultado polimórfico que sea compatible con el argumento de tipo.

Estoy utilizando EF 5.0 RC y el enfoque Code First.

¡Cualquier ayuda es muy apreciada!

+3

Esto puede ser debido a que su expresión implica 'Naranja' es un' Apple' – Eranga

+0

Lo habría pensado al definir mis FruitEntities como 'DbSet FruitEntities' la expresión implica que Orange y Apple son frutas? – Flo

+0

La cadena 'OfType' dice:" Filtra todas las manzanas de FruitEntities y luego filtra del resultado todas las manzanas que son naranjas ", lo cual solo tiene sentido si las naranjas son manzanas, es decir, la clase' Naranja 'hereda de la clase 'Apple'. ¿Qué quieres lograr con esa consulta? ¿Una lista combinada de naranjas y manzanas, es decir, todas las frutas que son manzanas ** o ** naranjas? – Slauma

Respuesta

7

Por lo que puedo decir, no puede aplicar Include en múltiples subtipos en una sola consulta de base de datos. Puede consultar un tipo (OfType<Apple>().Include(a => a.AppelFruitness)) y lo mismo para otro subtipo. El problema es que no puede concaturar los resultados en la misma consulta porque las colecciones de resultados tienen diferentes tipos genéricos (manzanas y naranjas).

Una opción sería ejecutar dos consultas y copiar la colección de resultados en una nueva colección del tipo base, como ya indicó en la sección de comentarios de su pregunta.

La otra opción (que solo necesitaría una consulta) es una proyección. Usted tendría que definir un tipo de proyección (también se puede proyectar en un tipo anónimo) ...

public class FruitViewModel 
{ 
    public FruitBase Fruit { get; set; } 
    public FruitnessFactor Factor { get; set; } 
} 

... y luego se puede utilizar la consulta:

List<FruitViewModel> fruitViewModels = context.FruitEntities 
    .OfType<Apple>() 
    .Select(a => new FruitViewModel 
    { 
     Fruit = a, 
     Factor = a.AppleFruitness 
    }) 
    .Concat(context.FruitEntities 
    .OfType<Orange>() 
    .Select(o => new FruitViewModel 
    { 
     Fruit = o, 
     Factor = o.OrangeFruitness 
    })) 
    .ToList(); 

Si no lo hace desactivar el seguimiento de cambios (mediante el uso de AsNoTracking) las propiedades de navegación son rellenados automáticamente cuando las entidades se vinculan al contexto ("Relación de corrección") lo que significa que se pueden extraer los frutos de la colección modelo de vista ...

IEnumerable<FruitBase> fruits = fruitViewModels.Select(fv => fv.Fruit); 

... y obtendrá las frutas incluyendo las propiedades FruitnessFactor.

Este código es bastante peculiar, pero se le ha pedido un enfoque directo sin necesidad de utilizar una proyección para varias veces sin éxito:

+0

Creo que voy por la solución de 2 consultas. Solo temo un impacto en el rendimiento si se tiene en cuenta que debo hacer la clasificación, la paginación y cosas por el estilo. Pero hasta ahora se ve bien. ¡Aclamaciones! – Flo

Cuestiones relacionadas