我有以下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
实例?
我尝试的另一种方法是创建从RevDev
到ItemDev
的第二个关系,但是EF也会在数据库中创建第二个外键列,这不是真正必要的......
答案 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默认执行此操作。我的代码中有另一个错误,为什么它不起作用...