【问题标题】:Query that Groups Parent, then Child, when fetching from IQueryable<GrandChild>从 IQueryable<GrandChild> 获取时,查询先对父分组,然后对子分组
【发布时间】:2013-02-20 00:51:00
【问题描述】:

让我们想象下面是我们的数据模型。我想查询玩具但返回结果以便我可以执行以下伪代码。

foreach (var parent in parents)
            {
                Console.WriteLine(parent.Name);

                foreach (var child in parent.Children)
                {
                    Console.WriteLine(child.Name);

                    foreach (var toy in child.Toys)
                    {
                        Console.WriteLine(toy.Name);
                    }
                }
            }

数据模型:

public class Parent
{
    public Guid ParentId { get; set; }
    public String Name { get; set; }
    public ICollection<Child> Children { get; set; } 
}
public class Child
{
    public Guid ChildId { get; set; }
    public Guid ParentId { get; set; }
    public Parent Parent { get; set; }
    public String Name { get; set; }
    public ICollection<Toy> Toys { get; set; } 
}
public class Toy
{
    public Guid ToyId { get; set; }
    public Guid ChildId { get; set; }
    public Child Child { get; set; }
    public String Name { get; set; }
    public bool IsCool { get; set; }
}

我尝试使用分组来执行此操作,但是当我尝试迭代分组时,我看到的只是 Key,它没有任何属性,因此我无法获取 Parent.Name 或 Child.Name。

提前致谢。

【问题讨论】:

    标签: linq linq-to-entities ef-code-first code-first


    【解决方案1】:

    你可以这样做:

    var query = from p in parents
                from c in p.Children
                from t in c.Toys
                select new { Parent = p.Name, Child = c.Name, Toy = t.Name }
    
    foreach (var a in query)
    {
        // write values.
    }
    

    实际上,这使用了SelectMany

    编辑

    在您发表评论后,我认为您要查找的不是分组。如果您有一个Parent 对象,实际上它的Children 已经在其中分组,因为每个父对象都有自己的集合。但也许您正在寻找一种填充集合的方法?这将由

    完成
    var query = from p in parents.Include(x => x.Children.Select(c => c.Toys));
    

    【讨论】:

    • 谢谢,但这并不是我想要的,它是我目前拥有的并且正在努力摆脱的。当我在示例中写出 Parent.Name 时,我真的需要父对象。该解决方案的每个项目都有父项,这是要携带的大量重复数据。我试图让每个客户只有一个记录。我认为我需要使用 GroupBy,你怎么看?
    • @HonorableChow 有什么反馈吗?
    【解决方案2】:

    LazyLoadingEnabled 设置为false,您将能够通过使用一个linq 查询来加载所有相关对象来做到这一点。

    请注意,如果儿童或玩具表中有大量相关数据,这可能会导致一些性能问题。

    context.ContextOptions.LazyLoadingEnabled = false;
    
    var parents = context.Parents.Select(x=>x).ToList();
    foreach(var parent in parents) {
        Console.WriteLine(parent.Name);
    
        foreach(var child in parent.Children) {
            Console.WriteLine(child.Name);
    
            foreach(var toy in child.Toys) {
                Console.WriteLine(toy.Name);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-14
      • 1970-01-01
      • 2016-10-15
      • 1970-01-01
      • 2012-04-17
      • 1970-01-01
      • 2021-07-13
      • 1970-01-01
      相关资源
      最近更新 更多