C# 使用实体框架将基类型定义查询为派生类型
我有以下POCO(首先使用代码和EF 6.0.0 alpha 3):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
公共类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
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();