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

C# 同时对集合和子集合进行排序,c#,linq,nhibernate,iqueryable,C#,Linq,Nhibernate,Iqueryable,我有一个IQueryable,需要按名称进行排序。每个产品都有一个IQueryable,它还需要按名称排序。我很难用Linq来表达这一点。我可以循环浏览产品并对每个类别列表进行排序,但看起来很混乱。希望Linq忍者有一个更聪明的解决方案 我的产品类看起来像: public class Product { public string Name { get; set; } public IQueryable<Category> Categories { get; set;

我有一个
IQueryable
,需要按
名称进行排序。每个
产品
都有一个
IQueryable
,它还需要按
名称
排序。我很难用Linq来表达这一点。我可以循环浏览产品并对每个类别列表进行排序,但看起来很混乱。希望Linq忍者有一个更聪明的解决方案

我的
产品
类看起来像:

public class Product {
    public string Name { get; set; }
    public IQueryable<Category> Categories { get; set; }
}
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这样的东西时,这会创建新的产品对象,本质上就是断开产品与NH会话的连接。

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


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

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


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

为什么不对可枚举项进行适当排序

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

正如其他人所说的,如果您已连接,这可能会执行得很差。

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

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

正如其他人所说,如果您已连接,这可能会执行得很差。

您不想以任何可能影响持久性的方式修改
产品
对象,也不想创建新的
产品
实例

因此,将其添加到
产品
类:

public IOrderedEnumerable<Category> CategoriesOrderedByName
{
  get { return this.Categories.OrderBy(y => y.Name); }
}
public IOrderedEnumerable CategoriesOrderedByName
{
获取{返回this.Categories.OrderBy(y=>y.Name);}
}
当您需要UI代码中的排序版本时,请使用
product.CategoriesOrderedByName


没有这一点,任何使用类的人都不会期望
类别
对象以任何方式排序。通过这种方式,您可以明确地告知类的消费者期望得到什么,并且您希望始终按排序顺序返回它们。您还可以使用
IOrderedEnumerable
作为返回类型,使用
ThenBy()

允许进一步的子排序。您不想以任何可能影响持久性的方式修改
Product
对象,也不想创建新的
Product
实例

因此,将其添加到
产品
类:

public IOrderedEnumerable<Category> CategoriesOrderedByName
{
  get { return this.Categories.OrderBy(y => y.Name); }
}
public IOrderedEnumerable CategoriesOrderedByName
{
获取{返回this.Categories.OrderBy(y=>y.Name);}
}
当您需要UI代码中的排序版本时,请使用
product.CategoriesOrderedByName


没有这一点,任何使用类的人都不会期望
类别
对象以任何方式排序。通过这种方式,您可以明确地告知类的消费者期望得到什么,并且您希望始终按排序顺序返回它们。您还可以使用
IOrderedEnumerable
作为返回类型,使用
ThenBy()

允许进一步的子排序。如果您希望按排序顺序枚举
产品
对象,并在每个
产品
中按排序顺序枚举
类别
,您可以这样做

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

看起来基本上就是这样,只是没有使用LINQ语法。

如果您想按排序顺序枚举
产品
对象,并且在每个
产品
中,您想按排序顺序枚举
类别
,您可以这样做

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

看起来基本上就是这样,只是没有使用LINQ语法。

我不认为这很混乱。分类产品和分类是两种概念上完全不同的操作;将它们在代码中分开并没有错。您试图达到的最终状态是什么?一份清单?我不认为这很混乱。分类产品和分类是两种概念上完全不同的操作;将它们在代码中分开并没有错。您试图达到的最终状态是什么?名单?