Linq至少有一个对象必须实现IComparable

时间:2014-04-26 06:34:44

标签: c# linq entity-framework linq-to-entities linq-to-objects

我正在尝试订购包含另一个实体列表的实体列表。我已经为所有实体实现了IComparable,但仍然获得了异常。我看到的所有示例都解决了您有一个列表并按该列表中的给定字段排序但不具有列表列表的问题。这个问题发生在Linq to Objects per below和Linq to Entities上。我错过了什么?

[TestClass]
public class OrderBy
{
    [TestMethod]
    public void OrderByTest()
    {
        var hobbies = new Collection<Hobby> { new Hobby { HobbyId = 1, Name = "Eating" }, new Hobby() { HobbyId = 2, Name = "Breathing" } };

        var p1 = new Person
        {
            PersonId = 1,
            Name = "A",
            PersonHobbies = new Collection<PersonHobby> { new PersonHobby() { PersonHobbyId = 1}}
        };
        var p2 = new Person
        {
            PersonId = 2,
            Name = "Z",
            PersonHobbies = new Collection<PersonHobby> { new PersonHobby() { PersonHobbyId = 2 }}
        };

        var people = new List<Person> { p1, p2 };
        var pplEnumerable = people.AsEnumerable();
        pplEnumerable = pplEnumerable.OrderByDescending(r => r.PersonHobbies.OrderByDescending(p => p.Hobby.Name));
        foreach (var person in pplEnumerable)
        {
            Console.WriteLine(person.Name);
        }
    }
    public class Person : IComparable
    {
        public int PersonId { get; set; }
        public string Name { get; set; }
        public virtual ICollection<PersonHobby> PersonHobbies { get; set; }
        public int CompareTo(object obj)
        {
            if (obj == null) return 1;
            var otherPerson = obj as Person;
            return PersonId.CompareTo(otherPerson.PersonId);
        }
    }
    public class PersonHobby : IComparable
    {
        public int PersonHobbyId { get; set; }
        public int HobbyId { get; set; }
        public virtual Person Person{ get; set; }
        public int PersonId { get; set; }
        public virtual Hobby Hobby { get; set; }
        public int CompareTo(object obj)
        {
            if (obj == null) return 1;
            var otherPersonHobby = obj as PersonHobby;
            return PersonHobbyId.CompareTo(otherPersonHobby.PersonHobbyId);
        }
    }
    public class Hobby : IComparable
    {
        public int HobbyId { get; set; }
        public string Name { get; set; }
        public int CompareTo(object obj)
        {
            if (obj == null) return 1;
            var otherHobby = obj as Hobby;
            return HobbyId.CompareTo(otherHobby.HobbyId);
        }
    }
}

1 个答案:

答案 0 :(得分:6)

默认情况下,您无法将排序应用于列表。你需要编写一个自定义类(类似EquatableList等)或使用LINQ Except&amp;将运算符相交以比较列表。

但根据你的评论,如果你正在寻找LINQ等价物:

select * from Person p join PersonHobby ph 
on ph.PersonId = p.PersonId join Hobby h 
on h.HobbyId = ph.HobbyId order by h.Name

然后可以实现:

var query = people.SelectMany(p => p.PersonHobbies)
                  .Join(hobbies, ph => ph.HobbyId, h => h.HobbyId, 
                        (ph, h) => new 
                        { 
                         Person = ph.Person, PersonHobby = ph, Hobby = h 
                        })
                  .OrderBy(r => r.Hobby.Name);

基本上我们在键上加入人物,人物爱好和爱好,并按照你的SQL中的提法,通过hobby.name字段对所有列进行排序和排序。