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

发布于 2024-09-16 22:07:37 字数 839 浏览 5 评论 0原文

我有一个 IQueryable 需要按 Name 排序。每个 Product 都有一个 IQueryable,也需要按 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 会话的连接。

I have an IQueryable<Product> that needs to be sorted by Name. Each Product has an IQueryable<Category> that also needs to be sorted by Name. I'm having a hard time expressing this in Linq. I could loop through the products and sort each category list, but it seems messy. Hoping a Linq ninja has a smarter solution.

My Product class looks like:

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

My Category class looks like:

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

Currently, I'm doing this:

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

The trouble is, when using something like NHibernate, this creates new Product objects, essentially disconnecting the product from the NH session.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

萌酱 2024-09-23 22:07:37

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

因此,将其添加到 Product 类中:

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

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

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

You don't want to modify the Product object in any way that could affect persistence and you don't want to create new Product instances.

So add this to Product class:

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

And use product.CategoriesOrderedByName instead when you need the sorted version in your UI code.

Without this anyone using your class has no expectation that the Category objects are sorted in any way. With this you are being explicit in informing consumers of your class what to expect and that you intend to always return them in a sorted order. You can also use IOrderedEnumerable<> as the return type to make allow further sub-sorting using ThenBy().

染火枫林 2024-09-23 22:07:37

也许这就是你想要的?但是,您不会获得每个产品都有一个类别列表的产品列表。使用 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。这是否意味着您正在使用此 LINQ 语句查询数据库?我不确定这转换为 SQL 的效果如何(性能方面)。

Maybe this is what you want? You do not get a list of products that each has a list of categories, however. That's impossible using LINQ because you can not alter a collection using LINQ, you can only make a new collection from an existing one (in my example p.Categories is the existing collection, SortedCategories the new one).

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

You say you have IQueryable's. Does that mean that you are querying against a database using this LINQ statement? I'm not sure how well this transforms to SQL (performance-wise).

忆伤 2024-09-23 22:07:37

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

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

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

Why not just sort the enumerable in place?

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

As others have stated, this may perform poorly if you're connected.

离笑几人歌 2024-09-23 22:07:37

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

If you want to enumerate over the Product objects in sorted order and within each Product you want the Categories in sorted order, you could do something like this.

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

It looks like this is basically what Ronald has, only without using LINQ syntax.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文