C# 使用实体框架将基类型定义查询为派生类型

C# 使用实体框架将基类型定义查询为派生类型,c#,.net,entity-framework,C#,.net,Entity Framework,我有以下POCO(首先使用代码和EF 6.0.0 alpha 3): 公共类RevBase { [关键] 公共int Id{get;set;} } 公共类项目库 { [关键] 公共int Id{get;set;} 公共列表Revs{get;set;} } 公共类RevDev:RevBase { 公共字符串内容{get;set;} } 公共类ItemDev:ItemBase { 公共字符串标题{get;set;} } 以下是上下文 public class MyContext : DbConte

我有以下POCO(首先使用代码和EF 6.0.0 alpha 3):

公共类RevBase
{
[关键]
公共int Id{get;set;}
}
公共类项目库
{
[关键]
公共int Id{get;set;}
公共列表Revs{get;set;}
}
公共类RevDev:RevBase
{
公共字符串内容{get;set;}
}
公共类ItemDev:ItemBase
{
公共字符串标题{get;set;}
}
以下是上下文

public class MyContext : DbContext
{
    DbSet<ItemDev> Items { get; set; }
}
公共类MyContext:DbContext
{
DbSet项{get;set;}
}
现在我想查询
context.Items.Include(I=>I.Revs)
,但告诉EF它应该以
RevDev
而不是
RevBase
的方式加载Revs

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


我尝试的另一种方法是创建从
RevDev
ItemDev
的第二个关系,但是EF也在DB中创建了第二个外键列,这实际上是不必要的…

刚刚发现Entity Framework默认情况下会这样做。我的代码中还有一个错误,为什么它不起作用…

刚刚发现实体框架在默认情况下会这样做。我的代码中还有一个错误,为什么它不起作用

将Revs加载为RevDev而不是RevBase

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

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

  • 使用显式加载(支持筛选):

    这是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();
    
    这只是一个数据库查询。自动关系修复应使用加载的
    RevDevs
    填充
    项.Revs
    集合

将Revs加载为RevDev而不是RevBase

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

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

  • 使用显式加载(支持筛选):

    这是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();
    
    这只是一个数据库查询。自动关系修复应使用加载的
    RevDevs
    填充
    项.Revs
    集合


  • 嗯,我可能误解了你的问题。。。(见我的回答)您实际上想要包括所有
    rev
    ,但是
    RevDev
    s应该具体化为
    RevDev
    ,而不是
    RevBase
    ,对吗?是的,默认情况下会发生这种情况。(我以为您只想筛选真正的
    RevDev
    s的
    Rev
    s,而不仅仅是
    RevBase
    )实际上,我所有的
    RevBase
    记录都是
    RevDevs
    ,但是通过我的代码中的一些错误,我的数据库中的
    RevDev
    记录被删除了,因此它们作为
    RevBase
    加载,直到我调试代码并检查了数据库记录,我才得到这些,很抱歉给您造成了任何不便…嗯,我可能误解了您的问题。。。(见我的回答)您实际上想要包括所有
    rev
    ,但是
    RevDev
    s应该具体化为
    RevDev
    ,而不是
    RevBase
    ,对吗?是的,默认情况下会发生这种情况。(我以为您只想筛选真正的
    RevDev
    s的
    Rev
    s,而不仅仅是
    RevBase
    )实际上,我所有的
    RevBase
    记录都是
    RevDevs
    ,但是通过我的代码中的一些错误,
    RevDev
    记录在我的数据库中被删除,因此它们作为
    RevBase
    加载,直到我调试了代码并检查了数据库记录,我才得到这些,很抱歉给您带来了任何不便……感谢您的输入,因为它包含了一些很好的提示,但正如我在自己的回答中所说,EF似乎已经注意到了这一点,因为我调试了我的代码,发现每个
    RevBase
    都有一个辅助
    RevDev
    记录作为
    RevDev
    加载,意思是
    项。Revs
    列表包含
    RevBase
    RevDev
    对象,然后我可以在代码中过滤该列表…感谢您的输入,因为它包含一些不错的提示,但正如我自己的回答中所述,EF似乎已经注意到了这一点,当我调试我的代码时,发现每个
    RevBase
    都有一个辅助的
    RevDev
    记录被加载为
    RevDev
    ,意思是
    项。Revs
    列表包含
    RevBase
    RevDev
    对象,然后我可以在代码中过滤该列表。。。
    var items = context.Items
        .Select(i => new
        {
            Item = i,
            RevDevs = i.Revs.Where(r => r is RevDev)
        })
        .AsEnumerable()
        .Select(a => a.Item)
        .ToList();