实体框架不查询派生类 - DbOfTypeExpression中的错误

Flo*_*Flo 7 polymorphism linq-to-entities entity-framework ef-code-first entity-framework-5

我有一个基类和两个派生类.

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

可悲的是,我对类设计影响不大 - >它们是从wsdl文件生成的.

然后我在BaseType上有一个属性来封装公共属性.计划是在我的网页浏览等中使用此属性.

我用着名的"Fruit-Example"来证明这个问题:

 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 { }
Run Code Online (Sandbox Code Playgroud)

在我的MVC控制器中,以下查询工作正常:

return View(context.FruitEntities
                           .OfType<Apple>().Include(a =>a.AppleFruitness)
                           .ToList());
Run Code Online (Sandbox Code Playgroud)

但是这个没有:

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

我得到的错误信息是:

DbOfTypeExpression需要一个表达式参数,其多态结果类型与type参数兼容.

我正在使用EF 5.0 RC和Code First方法.

任何帮助深表感谢!

Sla*_*uma 8

据我所知,您无法Include在单个数据库查询中应用多个子类型.您可以查询一个类型(OfType<Apple>().Include(a => a.AppelFruitness)),并查询另一个子类型.问题是您无法在同一查询中连接结果,因为结果集合具有不同的泛型类型(苹果和橙子).

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

另一个选项(只需要一个查询)是一个投影.您必须定义投影类型(您也可以投影到匿名类型)...

public class FruitViewModel
{
    public FruitBase Fruit { get; set; }
    public FruitnessFactor Factor { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

...然后可以使用查询:

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();
Run Code Online (Sandbox Code Playgroud)

如果您不禁用更改跟踪(通过使用AsNoTracking),当实体附加到上下文("关系修正")时,导航属性会自动填充,这意味着您可以从viewModel集合中提取水果...

IEnumerable<FruitBase> fruits = fruitViewModels.Select(fv => fv.Fruit);
Run Code Online (Sandbox Code Playgroud)

......你将获得包括FruitnessFactor属性在内的水果.

这段代码非常尴尬,但是没有使用投影的直接方法已经多次被要求没有成功:


归档时间:

查看次数:

8546 次

最近记录:

13 年,7 月 前