【问题标题】:Sorting collection and sub-collection at the same time同时对集合和子集合进行排序
【发布时间】:2011-04-06 09:50:05
【问题描述】:

我有一个IQueryable<Product>,需要按Name 排序。每个Product 都有一个IQueryable<Category>,也需要按Name 排序。我很难在 Linq 中表达这一点。我可以遍历产品并对每个类别列表进行排序,但看起来很乱。希望 Linq ninja 有更聪明的解决方案。

我的Product 类看起来像:

public class Product {
    public string Name { get; set; }
    public IQueryable<Category> Categories { get; set; }
}

我的Category 类看起来像:

public class Category { 
    public string Name { get; set; }
}

目前,我正在这样做:

 var myProducts = products.OrderBy(x => x.Name).Select(x => new Product { 
    Name = x.Name,
    Categories = x.Categories(y => y.Name)
});

问题在于,当使用 NHibernate 之类的东西时,这会创建新的 Product 对象,实际上是断开产品与 NH 会话的连接。

【问题讨论】:

  • 我不认为这很混乱。对产品进行排序和对类别进行排序是两个概念上完全不同的操作;在代码中将它们分开并没有错。
  • 您想要达到的最终状态是什么?一个列表?

标签: c# linq nhibernate iqueryable


【解决方案1】:

也许这就是你想要的?但是,您不会得到一个产品列表,每个产品都有一个类别列表。使用 LINQ 是不可能的,因为您无法使用 LINQ 更改集合,您只能从现有集合创建新集合(在我的示例中,p.Categories 是现有集合,SortedCategories 是新集合)。

from p in products
orderby p.Name
select new
{
    Product = p,
    SortedCategories = from c in p.Categories
                       orderby c.Name
                       select c
}

你说你有IQueryable's。这是否意味着您正在使用此 LINQ 语句查询数据库?我不确定这对 SQL 的转换效果如何(性能方面)。

【讨论】:

    【解决方案2】:

    为什么不直接对可枚举进行排序?

    products = products.OrderBy(x => x.Name);
    products.ToList().ForEach(x => x.Categories = x.Categories.OrderBy(y => y.Name));
    

    正如其他人所说,如果您已连接,这可能会表现不佳。

    【讨论】:

      【解决方案3】:

      您不想以任何可能影响持久性的方式修改Product 对象,并且您不想创建新的Product 实例。

      所以将这个添加到Product 类:

      public IOrderedEnumerable<Category> CategoriesOrderedByName
      {
        get { return this.Categories.OrderBy(y => y.Name); }
      }
      

      当您需要 UI 代码中的排序版本时,请改用 product.CategoriesOrderedByName

      没有这个,任何使用你的类的人都不会期望Category 对象会以任何方式排序。这样,您就可以明确地告知您的类的消费者会发生什么,并且您打算始终按排序顺序返回它们。您还可以使用IOrderedEnumerable&lt;&gt; 作为返回类型,以允许使用ThenBy() 进行进一步的子排序。

      【讨论】:

        【解决方案4】:

        如果您想按排序顺序枚举Product 对象,并且在每个Product 中您希望按排序顺序排列Categories,您可以这样做。

        var sorted = products
            .Select(
                p => new
                {
                    Product = p,
                    Categories = p.Categories.OrderBy(c => c.Name)
                }
            )
            .OrderBy(x => x.Product.Name);
        

        看起来这基本上就是 Ronald 所拥有的,只是没有使用 LINQ 语法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-04
          • 2011-03-29
          • 2015-09-18
          • 2011-10-20
          • 1970-01-01
          相关资源
          最近更新 更多