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,我怎样才能使这个查询工作?
OrderBy
函数返回一个集合,而不是单个元素:
OrderBy(x => x.Houses.Where(y => y.Owner == "Mike").Select(z => z.Score))
您需要将其限制为仅分数,而不是IEnumerable<double>
(如果Score
是double
(,即:
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的逻辑没有真正考虑(