gpt4 book ai didi

entity-framework - 在EF 4.1 Code-First中使用Include和/或Select方法时,如何对导航属性进行排序?

转载 作者:行者123 更新时间:2023-12-04 04:57:50 25 4
gpt4 key购买 nike

这是此处解释的问题的第二步:EF 4.1 code-first: How to load related data (parent-child-grandchild)?
@Slauma的指导下,我已经使用这种方法成功检索了数据:

var model = DbContext.SitePages
.Where(p => p.ParentId == null && p.Level == 1)
.OrderBy(p => p.Order) // ordering parent
.ToList();

foreach (var child in model) { // loading children
DbContext.Entry(child)
.Collection(t => t.Children)
.Query()
.OrderBy(t => t.Order) // ordering children
.Load();

foreach (var grand in child.Children) { // loading grandchildren
DbContext.Entry(grand)
.Collection(t => t.Children)
.Query()
.OrderBy(t => t.Order) // ordering grandchildren
.Load();
}
}

尽管这种方法可行,但它会将许多查询发送到数据库,而我正在寻找一种仅通过一个查询即可完成所有操作的方法。在 @Slauma的指导下(在以上链接的答案中进行了解释),我将查询更改为以下内容:
var model2 = DbContext.SitePages
.Where(p => p.ParentId == null && p.Level == 1)
.OrderBy(p => p.Order)
.Include(p => p.Children // Children: how to order theme???
.Select(c => c.Children) // Grandchildren: how to order them???
).ToList();

现在,如何在选择子代(和子代)时对其进行排序(如上面的第一个代码示例所示)?

最佳答案

不幸的是,急切的加载(Include)不支持对已加载的子集合进行任何过滤或排序。有三种选择可实现您想要的:

  • 具有显式排序加载的数据库多次往返。那是您问题中的第一个代码段。请注意,多次往返并不一定很糟糕,并且Include和嵌套的Include can lead to huge multiplication of transfered data between database and client
  • IncludeInclude(....Select(....))使用预加载,并在加载后对内存中的数据进行排序:
    var model2 = DbContext.SitePages
    .Where(p => p.ParentId == null && p.Level == 1)
    .OrderBy(p => p.Order)
    .Include(p => p.Children.Select(c => c.Children))
    .ToList();

    foreach (var parent in model2)
    {
    parent.Children = parent.Children.OrderBy(c => c.Order).ToList();
    foreach (var child in parent.Children)
    child.Children = child.Children.OrderBy(cc => cc.Order).ToList();
    }
  • 使用投影:
    var model2 = DbContext.SitePages
    .Where(p => p.ParentId == null && p.Level == 1)
    .OrderBy(p => p.Order)
    .Select(p => new
    {
    Parent = p,
    Children = p.Children.OrderBy(c => c.Order)
    .Select(c => new
    {
    Child = c,
    Children = c.Children.OrderBy(cc => cc.Order)
    })
    })
    .ToList() // don't remove that!
    .Select(a => a.Parent)
    .ToList();

  • 这仅是一次往返,如果您不禁用更改跟踪(在此查询中不要使用 .AsNoTracking()),则可以使用。此投影中的所有对象都必须加载到上下文中(需要第一个 ToList()的原因),并且上下文会将导航属性正确地绑在一起(这是一个称为“关系跨度”的功能)。

    关于entity-framework - 在EF 4.1 Code-First中使用Include和/或Select方法时,如何对导航属性进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7522784/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com