Smithy
Smithy

Reputation: 2190

How to tackle complex LINQ queries with outer join?

In my database I have roles and users, I also have user roles to tie the 2 together.

The problem is trying to get all users with their roles (if they have any, which they may not).

I use this query:

        return (from ur in db.UserRoles
                join r in db.Roles on ur.RoleID equals r.ID
                group r by ur.UserProfileID into ugr
                join u in db.UserProfiles on ugr.Key equals u.ID
                select new UserModel() {
                    ID = u.ID,
                    Username = u.UserName,
                    IsLockedOut = u.IsLockedOut,
                    LastLoginDate = u.LastLoginDate,
                    UserRoles = (from r in ugr
                                 select new RoleModel() {
                                     Name = r.Name,
                                     ID = r.ID
                                 }).ToList()
                }).ToList();

This works for users who have at least one role, but I also want users who do not have roles.

I'm currently trying to use http://msdn.microsoft.com/en-us/library/bb397895.aspx DefaultIfEmtpy(), but I don't know how and where to place it, meaning however I try my code does not compile.

How do I get all my Users, even if they do not have any UserRoles linked to them?

Upvotes: 1

Views: 70

Answers (1)

NinjaNye
NinjaNye

Reputation: 7126

Get the users first and include their roles from then

return db.UserProfiles
         .Include(up => up.UserRoles)
         .Select(u => new UserModel() {
                            ID = u.ID,
                            Username = u.UserName,
                            IsLockedOut = u.IsLockedOut,
                            LastLoginDate = u.LastLoginDate,
                            UserRoles = u.Roles
                                         .Select(r => new RoleModel() {
                                                        Name = r.Name,
                                                        ID = r.ID
                                                      })
                      })
         .ToList();

Update based on comments

return db.UserProfiles
         .Include(up => up.UserRoles)
         .Include("UserRoles.Roles") // <-- Added further include
         .Select(u => new UserModel() {
                            ID = u.ID,
                            Username = u.UserName,
                            IsLockedOut = u.IsLockedOut,
                            LastLoginDate = u.LastLoginDate,
                            // Modified this to use joining table
                            UserRoles = u.UserRoles 
                                         .Select(ur => new RoleModel() {
                                                        Name = ur.Role.Name,
                                                        ID = ur.RoleID
                                                      })
                      })
         .ToList();

Upvotes: 2

Related Questions