简体   繁体   中英

Complicated LINQ-query, joins, group and sum

I have these classes:

Book { UidBook, UidCategory, Score }  
Category { UidCategory, Score }  
Author { UidAuthor, Score }  
AuthorBook { UidAuthor, UidBook }  

These are organized in Lists<> and as you see there is a many-to-many relation between Book and Author.

What I want to do is to use linq to select new { UidBook, Score } where score is the sum of the book, category score and the score from each of the author belonging to the book.

I've been trying to work it out but my brain strangely enough stops working.

This might help you

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        public class Book
        {
            public int UidBook { get; set; }
            public int UidCategory { get; set; }
            public int Score { get; set; }
        }

        public class Category
        {
            public int UidCategory { get; set; }
            public int Score { get; set; }
        }

        public class Author
        {
            public int UidAuthor { get; set; }
            public int Score { get; set; }
        }

        public class AuthorBook
        {
            public int UidAuthor { get; set; }
            public int UidBook { get; set; }
        }

        static void Main(string[] args)
        {
            List<Category> categories = new List<Category>
            {
                new Category() { UidCategory = 1, Score = 25 },
                new Category() { UidCategory = 2, Score = 50 }
            };

            List<Book> books = new List<Book>
            {         
                new Book() { UidBook = 1, UidCategory = 1, Score = 44 },
                new Book() { UidBook = 2, UidCategory = 2, Score = 88 },
                new Book() { UidBook = 3, UidCategory = 1, Score = 99 },
                new Book() { UidBook = 4, UidCategory = 2, Score = 66 }
            };

            List<Author> authors = new List<Author>
            {
                new Author() { UidAuthor = 1, Score = 301 },
                new Author() { UidAuthor = 2, Score = 501 },
                new Author() { UidAuthor = 3, Score = 601 }
            };

            List<AuthorBook> authorBooks = new List<AuthorBook>
            {
                new AuthorBook() { UidAuthor = 1, UidBook = 1 },
                new AuthorBook() { UidAuthor = 1, UidBook = 2 },
                new AuthorBook() { UidAuthor = 2, UidBook = 3 },
                new AuthorBook() { UidAuthor = 3, UidBook = 4 }
            };

            var result = from book in books
                        join category in categories on book.UidCategory equals category.UidCategory
                        join authorBook in authorBooks on book.UidBook equals authorBook.UidBook
                        join author in authors on authorBook.UidAuthor equals author.UidAuthor
                        group new { book, category, authorBook, author } by book.UidBook into groupedResult
                        select new
                        {
                            UidBook = groupedResult.Key,
                            Score   = groupedResult.First().book.Score + 
                                      groupedResult.First().category.Score +
                                      groupedResult.Sum(s => s.author.Score)
                        };

            foreach (var item in result)
            {
                Console.WriteLine("{0} - {1}", item.UidBook, item.Score);
            }

            Console.Read();
        }
    }
}

I think you are looking for this:

var query = from b in BookList
            join c in CategoryList on b.UidCategory equals c.UidCategory
            join ab in AutorBookList on b.UidBook equals ab.UidBook
            join a in AuthorList on ab.UidAuthor equals a.UidAuthor
            group new { b, c, ab, a} by b.UidBook into g
            let bookScore = g.First().b.Score
            let categoryScore = g.First().c.Score
            let authorScore = g.Sum(x => x.a.Score)
            select new 
            {
              UidBook = g.Key,
              Score = bookScore + categoryScore + authorScore
            };
var result = from b in bookList
                     join authBook in authorBook on b.UidBook equals authBook.UidBook
                     join auth in authorList on authBook.UidAuthor equals auth.UidAuthor
                     join cat in categoryList on b.UidCategory equals cat.UidCategory
                     select new { b.UidBook, TotalScore = b.Score + auth.Score + cat.Score };

Clean up, group by, filter etc. on your actual relations. Example 1 book multiple authors and multiple categories, do you sum all the scores or average them? Weights etc....

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM