استخدم LINQ لتسلسل صفوف متعددة في صف واحد (خاصية CSV)

StackOverflow https://stackoverflow.com/questions/614542

سؤال

أنا أبحث عن LINQ المكافئ لـ Sybase's LIST() أو group_concat() في MySQL

سيتم تحويل:

User  Hobby
--------------
Bob   Football 
Bob   Golf 
Bob   Tennis 
Sue   Sleeping 
Sue   Drinking

ل:

User  Hobby
--------------
Bob   Football, Golf, Tennis 
Sue   Sleeping, Drinking
هل كانت مفيدة؟

المحلول

وهذا هو المشغل GroupBy. هل تستخدم LINQ إلى كائنات؟

وهنا مثال:

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);
            }
        }
    }
}

وهذا لا تجمع - يمكنك إدارة ما تبقى نفسك

نصائح أخرى

ونرى ما اذا كان هذا الحل يساعدك على:

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);
    }
}

وإعادة الجانب _concat لسؤالك، وذلك باستخدام:

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() );
    }
}

ووforeach إخراج في كوندي برونو والأجوبة جون السكيت يمكن أن تصبح:

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

... وستحصل على شكل الناتج نتيجة الدقيق الذي طلب (نعم، وأنا أعلم أن البعض الآخر قد حل بالفعل مشكلتك، ولكن من الصعب أن تقاوم!)

وإلا فإننا يمكن أن تفعل 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)});

لتفعل ذلك في بيان ينق واحد. لا توجد وسيلة أنصح الرمز، لكنه يظهر أنه يمكن القيام به.

            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));
        }

كل الإجابات ليست جيدة بما فيه الكفاية؛

لأن هذا استعلام قاعدة بيانات، لكننا جميعًا نفعل ذلك في الذاكرة فقط؛

الفرق هو أن بعض العمليات في الذاكرة ستحدث خطأ لا يمكن نقله لتخزين التعبير؛

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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top