views:

130

answers:

1

In my query I need to return instances of a class that doesn't have a default constructor (specifically this is in a custom Membership provider, and MembershipUser is the culprit)

var users = from l in context.Logins
    select new MembershipUser(
        Name,
        l.Username, // username
        l.Id, // provider key
        l.MailTo,
        l.PasswordQuestion,
        l.Notes.FirstOrDefault().NoteText,
        l.IsApproved,
        l.IsLockedOut,
        l.CreatedOn,
        l.LastLoginOn.HasValue ? l.LastLoginOn.Value : DateTime.MinValue,
        l.LastActivityOn.HasValue ? l.LastActivityOn.Value : DateTime.MinValue,
        DateTime.MinValue,
        l.LastLockedOutOn.HasValue ? l.LastLockedOutOn.Value : DateTime.MinValue
    );

is syntacitally correct, but results in a runtime error as Only parameterless constructors and initializers are supported in LINQ to Entities.

Update: as a workaround I'm now bringing the selection into a List (which resolves the runs the query expression) then I can select the new MembershipUser from that list.

var users = (from l in context.Logins
    select new { login = l }).ToList().Select(u => new MembershipUser (
Name,
u.login.Username, // username
u.login.Id, // provider key
u.email.MailTo,
u.login.PasswordQuestion,
u.login.Notes.FirstOrDefault().NoteText,
u.login.IsApproved,
u.login.IsLockedOut,
u.login.CreatedOn,
u.login.LastLoginOn.HasValue ? u.login.LastLoginOn.Value : DateTime.MinValue,
u.login.LastActivityOn.HasValue ? u.login.LastActivityOn.Value : DateTime.MinValue,
DateTime.MinValue,
u.login.LastLockedOutOn.HasValue ? u.login.LastLockedOutOn.Value : DateTime.MinValue
    );
+1  A: 

I think the problem is that you need to escape from LINQ to Entities and get to LINQ to Objects, which allows arbitrary method calls. The AsEnumerable extension method does this for you. How about this:

var users = from l in context.Logins.AsEnumerable() 
    select new MembershipUser( 
        Name, 
        l.Username, // username 
        l.Id, // provider key 
        l.MailTo, 
        l.PasswordQuestion, 
        l.Notes.FirstOrDefault().NoteText, 
        l.IsApproved, 
        l.IsLockedOut, 
        l.CreatedOn, 
        l.LastLoginOn ?? DateTime.MinValue, 
        l.LastActivityOn ?? DateTime.MinValue, 
        DateTime.MinValue, 
        l.LastLockedOutOn ?? DateTime.MinValue 
    ); 
Gabe
No because "LINQ to Entities does not recognize the method and this method cannot be translated into a store expression"
Ralph Shillington
I updated my answer to be more useful, I hope.
Gabe
Makes total sense now. Thanks.
Ralph Shillington