Mar*_*arc 4 c# linq entity-framework
我有以下实体:
public class Item
{
public int Id { get; set; }
public int? ParentId { get; set; }
public Item Parent { get; set; }
public List<Item> Children { get; set; }
public double PropertyA { get; set; }
public double PropertyB { get; set; }
...
}
Run Code Online (Sandbox Code Playgroud)
现在我想查询数据库并检索所有嵌套子节点的数据.我可以通过使用Eager Loading来实现这一点Include():
var allItems = dbContext.Items
.Include(x => Children)
.ToList();
Run Code Online (Sandbox Code Playgroud)
但是,我想做以下投射,而不是Eager Loading:
public class Projection
{
public int Id { get; set; }
public List<Projection> Children { get; set; }
public double PropertyA { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
是否可以通过一次选择仅检索所需的数据?我们正在使用Entity Framework 6.1.3.
编辑:
这是我到目前为止所尝试的.我真的不知道如何告诉EF以Projection比他们父母相同的方式映射所有孩子.
EntityFramework.SqlServer.dll中出现未处理的"System.NotSupportedException"类型异常
附加信息:"Projection"类型出现在单个LINQ to Entities查询中的两个结构不兼容的初始化中.A型可以在同一个查询两个地方被初始化,但只有当同一属性在两个地方设置和这些属性以相同的顺序设置.
var allItems = dbContext.Items
.Select(x => new Projection
{
Id = x.Id,
PropertyA = x.PropertyA,
Children = x.Children.Select(c => new Projection()
{
Id = c.Id,
PropertyA = c.PropertyA,
Children = ???
})
})
.ToList();
Run Code Online (Sandbox Code Playgroud)
一般来说,您无法在单个SQL查询中加载未知无限深度的递归结构,除非您批量加载所有可能相关的数据,无论它们是否属于所请求的结构.
因此,如果您只想限制已加载的列(排除PropertyB),但可以加载所有行,结果可能如下所示:
var parentGroups = dbContext.Items.ToLookup(x => x.ParentId, x => new Projection
{
Id = x.Id,
PropertyA = x.PropertyA
});
// fix up children
foreach (var item in parentGroups.SelectMany(x => x))
{
item.Children = parentGroups[item.Id].ToList();
}
Run Code Online (Sandbox Code Playgroud)
如果要限制已加载的行数,则必须接受多个数据库查询才能加载子条目.例如,加载单个子集合可能看起来像这样
entry.Children = dbContext.Items
.Where(x => x.ParentId == entry.Id)
.Select(... /* projection*/)
.ToList()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6091 次 |
| 最近记录: |