在LINQ嵌套列表中使用group by

时间:2018-11-01 07:00:19

标签: c# xml linq

我正在使用linq c#查询对基于Library和Books的离散组合进行分组。 我在每个图书馆内都有图书馆清单和书籍清单 输入XML:

<Libraries>
    <LibraryCode value="1">test</LibraryCode>
    <LibraryArea>XYZ</LibraryArea>
    <Books BookID="Book_ID1">
        <BookName>Name1</BookName>
        <BookCode code="1">Code1</BookCode>
    </Books>
    <Books BookID="Book_ID2">
        <BookName>Name2</BookName>
        <BookCode code="1">Code1</BookCode>
    </Books>
</Libraries>

<Libraries>
    <LibraryCode value="2">test</LibraryCode>
    <LibraryArea>ABC</LibraryArea>
    <Books BookID="Book_ID1">
        <BookName>Name1</BookName>
        <BookCode code="1">Code1</BookCode>
    </Books>
    <Books BookID="Book_ID2">
        <BookName>Name2</BookName>
        <BookCode code="1">Code1</BookCode>
    </Books>
</Libraries>

<Libraries>
    <LibraryCode value="3">test</LibraryCode>
    <LibraryArea>ABC</LibraryArea>
    <Books BookID="Book_ID3">
        <BookName>Name3</BookName>
        <BookCode code="3">Code3</BookCode>
    </Books>
</Libraries>

<Libraries>
    <LibraryCode value="4">test</LibraryCode>
    <LibraryArea>ABC</LibraryArea>
    <Books BookID="Book_ID3">
        <BookName>Name3</BookName>
        <BookCode code="3">Code3</BookCode>
    </Books>
</Libraries>

<Libraries>
    <LibraryCode value="5">test</LibraryCode>
    <LibraryArea>ABC</LibraryArea>
    <Books BookID="Book_ID5">
        <BookName>Name5</BookName>
        <BookCode code="5">Code5</BookCode>
    </Books>
</Libraries>

期望的XML:

<Libraries>
    <LibraryCode value="1">test</LibraryCode>
    <LibraryArea>XYZ</LibraryArea>
    <Books BookID="Book_ID1">
        <BookName>Name1</BookName>
        <BookCode code="1">Code1</BookCode>
    </Books>
    <Books BookID="Book_ID2">
        <BookName>Name2</BookName>
        <BookCode code="1">Code1</BookCode>
    </Books>
</Libraries>

<Libraries>
    <LibraryCode value="3">test</LibraryCode>
    <LibraryArea>ABC</LibraryArea>
    <Books BookID="Book_ID3">
        <BookName>Name3</BookName>
        <BookCode code="3">Code1</BookCode>
    </Books>
</Libraries>

<Libraries>
    <LibraryCode value="5">test</LibraryCode>
    <LibraryArea>ABC</LibraryArea>
    <Books BookID="Book_ID5">
        <BookName>Name5</BookName>
        <BookCode code="5">Code1</BookCode>
    </Books>
</Libraries>

请注意,第一条记录和第二条记录中的书籍组合相同,即LibraryCode值分别为“ 1”和“ 2”。尽管可能会有所不同,但我只需要一条图书馆记录(“ 1”或“ 2”)基于 BookID 的信息,因为第一和第二条记录的书记录相同 同样,对于第4和第5条记录,我只需要一个,而我需要第5个库记录,因为它与Library and Books的组合不同。 这里的图书馆和书籍是清单。 我正在使用的代码

var result= libraries.GroupBy(x=>x.Books.Select(s=>s.BookID)).Select(grp=>grp.ToList()).ToList();

这似乎不起作用。 任何帮助将非常感激 。 谢谢

2 个答案:

答案 0 :(得分:0)

默认情况下,几乎所有引用类型都是按引用进行比较的,因此要么需要自定义比较器来按值进行比较,要么需要按值进行比较的按类型分组:

libraries.GroupBy(l => string.Join(",", l.Books.Select(b => b.BookID)))

答案 1 :(得分:0)

实际上,您通过引用比较了两个书本ID集合。我猜想自定义比较器在这种情况下会更合适,您应该将其作为按键选择器分组后的第二个参数添加。

libraries.GroupBy(x=>x.Books.Select(s=>s.BookID), new BookIdsComparer ())

public class BookIdsComparer : IEqualityComparer<IEnumerable<string>>
{
    public bool Equals(IEnumerable<string> bookIds1, IEnumerable<string> bookIds2)
    {
        return bookIds1.Count() == bookIds2.Count() 
            && bookIds1.Intersect(bookIds2).Count() == bookIds1.Count();
    }

    public int GetHashCode(IEnumerable<string> bookIds)
    {
        var result = 1;
        foreach (var bookId in bookIds)
        {
            result ^= bookId.GetHashCode();
        }

        return result;
    }
}
相关问题