У меня был бы запрос, похожий на этот.Если вы профилируете запрос, вы заметите, что часть STUFF ... FOR XML PATH вычисляется в памяти .NET вместо SQL.
var test = (
from u in ctx.Users
join ur in ctx.UserRoles on u.Id equals ur.UserId
join r in ctx.Roles on ur.RoleId equals r.Id
group r by u into g
select new { User = g.Key, Roles = string.Join(",", g.Select(y => y.Name)) }
);
Примечание: Работать сзапрос, сохраняющий пользователя как объект, вместо расширения всех его свойств