使用Entity Framework将基类型定义为派生类型

时间:2013-03-10 12:38:30

标签: c# .net entity-framework

我有以下POCO(使用Code First和EF 6.0.0 alpha 3):

public class RevBase
{
    [Key]
    public int Id{ get; set; }
}

public class ItemBase
{
    [Key]
    public int Id { get; set; }

    public List<RevBase> Revs { get; set; }
}

public class RevDev : RevBase
{
    public string Content { get; set; }
}

public class ItemDev : ItemBase
{
    public string Title { get; set; }
}

以及以下背景

public class MyContext : DbContext
{
    DbSet<ItemDev> Items { get; set; }
}

现在我想查询context.Items.Include(i => i.Revs),但告诉EF它应该将Revs加载为RevDev而不是RevBase

是可能还是我需要将它们加载为RevBase并进行另一次查询以获取相应的RevDev实例?

我尝试的另一种方法是创建从RevDevItemDev的第二个关系,但是EF也会在数据库中创建第二个外键列,这不是真正必要的......

2 个答案:

答案 0 :(得分:1)

  

将Revs加载为RevDev而不是RevBase

如果给定的RevBase不是RevDev,则无法将其加载为 RevDev。 (不是每只动物都是狗。你不能让每只动物都成为狗,有些是猫。)

实际上,我认为您需要的是类型的过滤器,这在使用Include时通常是个问题,因为它根本不支持任何过滤。我看到你有两个选择:

  • 使用显式加载(支持过滤):

    var items = context.Items.ToList();
    foreach (var item in items)
        context.Entry(item).Collection(i => i.Revs).Query()
            .Where(r => r is RevDev)
            .Load();
    

    这些是1 + N个单独的数据库查询。

  • 使用投影:

    var items = context.Items
        .Select(i => new
        {
            Item = i,
            RevDevs = i.Revs.Where(r => r is RevDev)
        })
        .AsEnumerable()
        .Select(a => a.Item)
        .ToList();
    

    这只是一个数据库查询。自动关系修正应使用加载的Item.Revs填充RevDevs集合。

答案 1 :(得分:0)

刚刚发现Entity Framework默认执行此操作。我的代码中有另一个错误,为什么它不起作用...