Use LINQ to concatenate multiple rows into single row (CSV property)

后端 未结 6 1146
[愿得一人]
[愿得一人] 2020-11-27 19:42

I\'m looking for the LINQ equivalent to the Sybase\'s LIST() or MySQL\'s group_concat()

It\'ll convert:

User  Hobby
--------------
Bob   Football 
Bo         


        
相关标签:
6条回答
  • 2020-11-27 20:11

    re the _concat aspect of your question, using:

    static class EnumerableExtensions 
    {  
        public static String AsJoined( this IEnumerable<String> enumerable )
        {
            return AsJoined( enumerable, "," );
        }
    
        public static String AsJoined( this IEnumerable<String> enumerable, String separator )
        {
            return String.Join( separator, enumerable.ToArray() );
        }
    }
    

    The outputting foreach in bruno conde and Jon Skeet's answers can become:

    Console.WriteLine( "User:\tHobbies");
    foreach ( var group in groupedUsers )
        Console.WriteLine( "{0}:\t{1}", group.Key, group.Select( g => g.Hobby ).AsJoined( ", " ) );
    

    ... and you'll get the precise result output format you asked for (yes, I know the others have already solved your problem, but its hard to resist!)

    0 讨论(0)
  • 2020-11-27 20:14

    See if this solution helps you:

    List<User> users = new List<User>() 
    { 
        new User {Name = "Bob", Hobby = "Football" },
        new User {Name = "Bob", Hobby = "Golf"},
        new User {Name = "Bob", Hobby = "Tennis"},
        new User {Name = "Sue", Hobby = "Sleeping"},
        new User {Name = "Sue", Hobby = "Drinking"}
    };
    
    var groupedUsers = from u in users
             group u by u.Name into g
             select new
             {
                 Name = g.First<User>().Name,
                 Hobby = g.Select(u => u.Hobby)
             };
    
    
    foreach (var user in groupedUsers)
    {
        Console.WriteLine("Name: {0}", user.Name);
        foreach (var hobby in user.Hobby)
        {
            Console.WriteLine("Hobby: {0}", hobby);
        }
    }
    
    0 讨论(0)
  • 2020-11-27 20:17

    To do it in one Linq Statement. There is no way I'd recommend the code, but it shows that it could be done.

                var groupedUsers = from user in users
                               group user by user.User into userGroup
                               select new
                               {
                                   User = userGroup.Key,
                                   userHobies =
                                       userGroup.Aggregate((a, b) => 
                                           new { User = a.User, Hobby = (a.Hobby + ", " + b.Hobby) }).Hobby
                               }
                                ;
            foreach (var x in groupedUsers)
            {
                Debug.WriteLine(String.Format("{0} {1}", x.User, x.userHobies));
            }
    
    0 讨论(0)
  • 2020-11-27 20:25

    That's the GroupBy operator. Are you using LINQ to Objects?

    Here's an example:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    public class Test
    {
        static void Main()
        {
            var users = new[]
            {
                new { User="Bob", Hobby="Football" },
                new { User="Bob", Hobby="Golf" },
                new { User="Bob", Hobby="Tennis" },
                new { User="Sue", Hobby="Sleeping" },
                new { User="Sue", Hobby="Drinking" },
            };
    
            var groupedUsers = users.GroupBy(user => user.User);
    
            foreach (var group in groupedUsers)
            {
                Console.WriteLine("{0}: ", group.Key);
                foreach (var entry in group)
                {
                    Console.WriteLine("  {0}", entry.Hobby);
                }
            }
        }
    }
    

    That does the grouping - can you manage the rest yourself?

    0 讨论(0)
  • 2020-11-27 20:28

    Or else we can do the following-

    var users = new[]
                    {
                    new { User="Bob", Hobby="Football" },
                    new { User="Bob", Hobby="Golf" },
                    new { User="Bob", Hobby="Tennis" },
                    new { User="Sue", Hobby="Sleeping" },
                    new { User="Sue", Hobby="Drinking" },
                    };
    
                    var userList = users.ToList();
                    var ug = (from user in users
                              group user by user.User into groupedUserList
                              select new { user = groupedUserList.Key, hobby = groupedUserList.Select(g =>g.Hobby)});
    
                    var ug2 = (from groupeduser in ug
                              select new{ groupeduser.user, hobby =string.Join(",", groupeduser.hobby)});
    
    0 讨论(0)
  • 2020-11-27 20:30

    all answers is not good enough;

    because this is a db query,but all of us do that just in memory;

    diff is that some operation in memory will occuce a error can't trans to store expression;

    var list = db.Users.GroupBy(s=>s.User).
                 select(g=>new{user=g.Key,hobbys=g.select(s=>s.Hobby)}); // you can just do that from db
    
    var result=list.ToList(); // this is important,to query data to memory;
    
    var result2 = result.select(g=>new{user=g.Key,hobbyes=string.join(",",g.hobbyes)}; //then,do what you love in memory
    
    0 讨论(0)
提交回复
热议问题