LINQ OrderBy 不起作用

本文关键字:不起作用 OrderBy LINQ | 更新日期: 2023-09-27 18:19:56

我有以下代码:

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.

我正在尝试查询迈克家按迈克家在那个地方的分数排序的地方(你可以从上面看到这个想法(。一个地方有一个房屋列表。重要提示:您可以假设每个地方没有一个业主可以拥有多于一栋房屋!

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

LINQ OrderBy 不起作用

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

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

您需要将其限制为仅分数,而不是IEnumerable<double>(如果Scoredouble(,即:

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

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

在这里,

我只剪掉了你的OrderBy子句:

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

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

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

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())

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

与 Reed 的答案相似

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

(切线:您的第一个 Where((。计数> 0 可能应该只是一个 Any(((

正如其他答案所指出的,OrderBy 只需要提供分数。或者,你可以让你的房子类实现 IComparable,以允许你直接对房子进行排序。

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

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

(关于 OrderBy vs OrderByDescending 和 Max vs Min的逻辑没有真正考虑(