同时对集合和子集合进行排序

时间:2010-08-31 17:26:33

标签: c# linq nhibernate iqueryable

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

我的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会话断开连接。

4 个答案:

答案 0 :(得分:1)

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

所以将此添加到Product类:

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

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

如果没有这个,任何使用你的类的人都不会期望Category对象以任何方式排序。通过这种方式,您可以明确告知消费者您的课程有什么期望,并且您打算始终按照排序顺序返回它们。您还可以使用IOrderedEnumerable<>作为返回类型,以允许使用ThenBy()进行进一步的子排序。

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

如果您想按排序顺序枚举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语法。