【问题标题】:LINQ OrderBy is not workingLINQ OrderBy 不起作用
【发布时间】:2026-02-23 04:40:01
【问题描述】:

我有以下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OrderByElementSubelement
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Place> places = new List<Place>();
            places.Add(new Place { Address = "Fifth Street", Score = 29, Houses = new List<House> { new House { Owner = "Mike", Score = 32 }, new House { Owner = "Bobby", Score = 3 } } });
            places.Add(new Place { Address = "Sixth Street", Score = 29, Houses = new List<House> { new House { Owner = "Mike", Score = 42 }, new House { Owner = "Ted", Score = 45 } } });
            places.Add(new Place { Address = "Seventh Street", Score = 29, Houses = new List<House> { new House { Owner = "Randy", Score = 84 }, new House { Owner = "William", Score = 1 } } });
            var placesWithMikesHouseOrderedByMikesHouseScore = places.Where(x => x.Houses.Where(y => y.Owner == "Mike").Count() > 0).OrderBy(x => x.Houses.Where(y => y.Owner == "Mike").Select(z => z.Score)).ToList();
        }

        public class Place
        {
            public string Address { get; set; }
            public int Score { get; set; }
            public List<House> Houses { get; set; }
        }

        public class House
        {
            public string Owner { get; set; }
            public int Score { get; set; }
        }
    }
}

它抛出这个异常:

An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll

Additional information: At least one object must implement IComparable.

我正在尝试根据 Mike 的房子在那个地方的分数来查询 Mike 的房子的地方(你可以从上面看到这个想法)。一个地方有一个房屋清单。 重要提示:您可以假设每个业主都不能拥有超过一所房子!

为什么它要一个对象在这里实现 IComparable,我怎样才能使这个查询起作用?

【问题讨论】:

    标签: c# .net linq exception linq-to-objects


    【解决方案1】:

    您的 OrderBy 函数返回一个集合,而不是单个元素:

    OrderBy(x => x.Houses.Where(y => y.Owner == "Mike").Select(z => z.Score))
    

    您需要将其限制为仅分数,而不是 IEnumerable&lt;double&gt;(如果 Scoredouble),即:

    OrderBy(x => x.Houses.First(y => y.Owner == "Mike").Score)
    

    请注意,如果没有以"Mike" 作为所有者的房子,这将抛出,但是,您的第一个过滤器应该处理它。

    【讨论】:

      【解决方案2】:

      这里我只剪掉了你的OrderBy 子句:

      OrderBy(x => x.Houses.Where(y => y.Owner == "Mike").Select(z => z.Score))
      

      您的问题是,即使 x.Houses.Where().Select() 只有一个元素,它仍然返回一个 IEnumerable,它没有实现 IComparable 并且对订购无效。

      您只想选择该集合中的第一项,因此您有几个选择:

      OrderBy(x => x.Houses.Where(y => y.Owner == "Mike").Select(z => z.Score).Single())
      OrderBy(x => x.Houses.Where(y => y.Owner == "Mike").Select(z => z.Score).SingleOrDefault())
      OrderBy(x => x.Houses.Where(y => y.Owner == "Mike").Select(z => z.Score).First())
      OrderBy(x => x.Houses.Where(y => y.Owner == "Mike").Select(z => z.Score).FirstOrDefault())
      

      每一个都有不同的行为如果集合包含多个元素,相同的行为如果它只包含一个元素。

      【讨论】:

        【解决方案3】:

        类似于里德的回答

        var foo = places.Where(p => p.Houses.Any(h => h.Owner == "Mike"))
                        .OrderBy(p => p.Houses.Single(h => h.Owner == "Mike").Score);
        

        (Tangent: 你的第一个 Where().Count > 0 应该只是一个 Any())

        正如其他答案所指出的,OrderBy 只需要提供分数。或者,您可以make your House class implement IComparable 让您直接对房屋进行分类。

        如果您取消了迈克在一个地方只拥有一所房子的要求,您可能希望迈克在一个地方的所有房子都获得最佳分数,在这种情况下,您可以调整为以下内容...

        .OrderBy(p => p.Houses.Where(h => h.Owner == "Mike").Max(h => h.Score));
        

        (未真正考虑关于 OrderBy 与 OrderByDescending 和 Max 与 Min 的逻辑)

        【讨论】: