tags:

views:

77

answers:

2
+3  Q: 

LINQ TO SQL Query

I have a LINQ TO SQL query which retrieves all the users along with their roles:

var userRoles = from u in db.GetTable<User>()
                            join ur in db.GetTable<UserRole>()
                                on u.UserID equals ur.UserID
                            join r in db.GetTable<Role>()
                                on ur.RoleID equals r.RoleID
                                orderby u.UserID
                            select new
                                       {
                                           u.UserID,
                                           r.RoleName
                                       };

A user in the system can have multiple roles. The result of this query (in a table format) looks like:

1 Admin
1 Employee
2 Employee
3 Employee

How can I re-write this query to return all user roles as comma separated values like:

1 Admin, Employee
2 Employee
3 Employee

+1  A: 

Hey Kumar, I created a small console app to mimic the data I believe you have. I think it exhibits the behavior you are looking for though. It's not the greatest code in the world, but I think the algorithm is the point. I just threw together a quick override of ToString() to display the data correctly.

The main change I did was to create a defined class for the data to be displayed, and break the linq query into two separate pieces:

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

namespace Test
{
    class Program
    {
        static void Main()
        {
            var users = new List<User>
                            {
                                new User
                                    {
                                        UserID = "1"
                                    },
                                new User
                                    {
                                        UserID = "2"
                                    },
                                new User
                                    {
                                        UserID = "3"
                                    }
                            };

            var roles = new List<Role>
                            {
                                new Role
                                    {
                                        RoleID = "1",
                                        RoleName = "Admin"
                                    },
                                new Role
                                    {
                                        RoleID = "2",
                                        RoleName = "Employee"
                                    }
                            };

            var userRoles = new List<UserRole>
                                {
                                    new UserRole
                                        {
                                            UserID = "1",
                                            RoleID = "1"
                                        },

                                    new UserRole
                                        {
                                            UserID = "1",
                                            RoleID = "2"
                                        },

                                    new UserRole
                                        {
                                            UserID = "2",
                                            RoleID = "2"
                                        },

                                    new UserRole
                                        {
                                            UserID = "3",
                                            RoleID = "2"
                                        }
                                };

            var userRoles2 = from u in users
                             orderby u.UserID
                             select new UserList
                             {
                                 UserID = u.UserID,
                                 Roles = (from r in roles
                                            join ur in userRoles
                                            on u.UserID equals ur.UserID
                                            where ur.RoleID == r.RoleID
                                            select r).ToList()
                             };

            foreach (var item in userRoles2)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
    }

    public class User
    {
        public string UserID;
    }

    public class UserRole
    {
        public string UserID;
        public string RoleID;
    }

    public class Role
    {
        public string RoleID;
        public string RoleName;
    }

    public class UserList
    {
        public string UserID;
        public List<Role> Roles;

        public override string ToString()
        {
            string output = UserID + " ";
            foreach (var role in Roles)
            {
                output += role.RoleName + ", ";
            }
            output = output.Substring(0, output.Length - 2);
            return output;
        }
    }
}
Andrew Dunaway
+1  A: 

This is one way of doing it, have not tested it:

    from u in db.GetTable<User>()   
                      join ur in db.GetTable<UserRole>()   
                            on u.UserID equals ur.UserID   
                      join r in db.GetTable<Role>()   
                            on ur.RoleID equals r.RoleID   
                      orderby u.UserID
                      group u by u.UserID into g    
                      select new   
                                {   
                                    UserId = g.Key,   
                                    Roles = String.Join (" ,", g.UserRoles.SelectMany(c => c.Roles).Select(p=> p.RoleName).ToArray()))
                                };   
Victor