5

我有一个基类和两个派生类。实体框架不查询派生类 - DbOfTypeExpression中的错误

每个派生类实现与属性相同的类型 - 唯一的区别是属性名称。

可悲的是我没有太多的影响类设计 - >他们已经从一个wsdl文件生成。

然后我在BaseType上有一个属性来封装公共属性。该计划是在我的网站访问量等

我已经使用了著名的“水果例”来说明问题使用这个属性:

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 { } 

在我的MVC控制器,下面的查询工作精绝:

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

但是这一次没有:

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

该错误消息我得到的是:

DbOfTypeExpression需要一个具有与type参数兼容的多态结果类型的表达式参数。

我使用EF 5.0 RC和Code First方法。

任何帮助非常感谢!

+3

这可能是因为你的表达意味着'Orange'是'Apple' – Eranga

+0

我想通过将我的FruitEntities定义为'DbSet FruitEntities'表达意味着橙和苹果是水果?! – Flo

+0

'OfType'链说:“过滤来自FruitEntities的所有苹果,然后从结果中筛选出所有橙子的苹果”,这只有在桔子是苹果时才有意义,即橙色类继承自Apple类。你想用这个查询来达到什么目的?桔子和苹果的组合清单,即所有苹果**或**桔子的水果? – Slauma

回答

7

据我可以告诉你,不能在单个数据库查询中对多个子类型应用Include。您可以查询一种类型(OfType<Apple>().Include(a => a.AppelFruitness)),另一种子类型也可以查询。问题在于,无法在相同的查询中对结果进行连接,因为结果集合具有不同的通用类型(苹果和桔子)。

一种选择是运行两个查询并将结果集合复制到基本类型的新集合中 - 正如您在问题下的注释部分中已经指出的那样。

其他选项(只需要一个查询)就是一个投影。你必须定义一个投影类型(你也可以投射到一个匿名类型)...

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

...然后可以使用查询:如果你不

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(); 

禁用更改跟踪(通过使用AsNoTracking)当实体得到重视,这意味着你可以提取视图模型收集果实上下文(“关系修正”)的导航属性都会自动填充......

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

...您将获得水果,其中包括FruitnessFactor属性。

此代码是非常尴尬的,但没有使用投影直接的办法已经被问了好几次都没有成功:

+0

我认为我正在为2查询解决方案。如果考虑到我需要做排序,分页和类似的东西,我只会担心性能的影响。但到目前为止,它看起来不错。干杯! – Flo