bman
bman

Reputation: 3780

How to Execute a method inside LINQ to Entities'

var users = from u in db.UserProfiles select new UsersViewModel{ 
                            UserName = u.UserName,
                            UserId = u.UserId,
                            IsDisabled = u.IsDisabled,
                            Role = Roles.GetRolesForUser(u.UserName).FirstOrDefault()
                        };

I would like to select the roles from the database and create a list of UsersViewModel. However Entity Framework is trying to execute the projection on the SQL side, where there is no equivalent to Roles.GetRolesForUser.

What would be an alternative to this or how am I suppose to execute any method inside the query?

Upvotes: 3

Views: 1482

Answers (3)

Khan
Khan

Reputation: 18142

You can force the query to execute before creating the ViewModels by adding ToList():

var users = from u in db.UserProfiles.ToList() 
    select new UsersViewModel{ 
        UserName = u.UserName,
        UserId = u.UserId,
        IsDisabled = u.IsDisabled,
        Role = Roles.GetRolesForUser(u.UserName).FirstOrDefault()
    };

As CodeMonkey1313 noted, I strongly suggest you apply some sort of filter in your query:

var users = from u in db.UserProfiles
    .Where( x => /* apply filter here */ )
    .ToList() //Force query to execute
    select new UsersViewModel { 
        UserName = u.UserName,
        UserId = u.UserId,
        IsDisabled = u.IsDisabled,
        Role = Roles.GetRolesForUser(u.UserName).FirstOrDefault()
    };

Upvotes: 1

FrankPl
FrankPl

Reputation: 13315

You can convert your Queryable to an Enumerable that executes locally:

var users = (from u in db.UserProfiles select new UsersViewModel{ 
                        UserName = u.UserName,
                        UserId = u.UserId,
                        IsDisabled = u.IsDisabled)}
                     ).AsEnumerable()
                      .Select(u => new { 
                        UserName = u.UserName,
                        UserId = u.UserId,
                        IsDisabled = u.IsDisabled,
                        Role = Roles.GetRolesForUser(u.UserName) })
                      .FirstOrDefault()

Upvotes: -1

CodeMonkey1313
CodeMonkey1313

Reputation: 16011

The easiest is to get the data you want from SQL, then after the query executes, iterate through the results and populate the additional details from the function in your code.

Example:

var users = (from u in db.UserProfiles select new UsersViewModel{ 
                            UserName = u.UserName,
                            UserId = u.UserId,
                            IsDisabled = u.IsDisabled
                        }).ToList();
foreach(var user in users){
    user.Role = Roles.GetRolesForUser(u.UserName).FirstOrDefault();
}

The key to remember here is to separate out what you're doing (understanding the separation of concerns in your architecture). Take care of the SQL first, then augment the data from other sources, in your case the Role Provider.

Upvotes: 2

Related Questions