1

I create class Employee:

public class Employees : BaseModel
{
    [Key]
    public int EmployeeId { get; set; }
   // [ohter parameter]
    public int? DepartmentId { get; set; }
    public virtual Departments Departments { get; set; }
    public int? OccupationId { get; set; }
    public virtual Occupations Occupations { get; set; }
}

I want to create a view model.

public class Employee_ViewModel 
{
    public Employee_ViewModel(Employees item)
    {
        this.EmployeeId = item.EmployeeId;
        //[other parameter]
        this.DepartmentId = item.DepartmentId;
        this.OccupationId = item.OccupationId;
    }

    public int EmployeeId { get; set; }
    //[other parameter]
    public string DepartmentName { get; set; }
    public string OccupationName { get; set; }
}

my method which returns Employee_ViewModel look like:

 List<Employee_ViewModel> item = contex.Employees.Where(w => w.IsActive == true && w.IsVisible == true)
                                     .Include(i => i.Departments)
                                     .Include(i => i.Occupations)
                                     .Select(s => new Employee_ViewModel(s)
                                     {
                                         OccupationName = s.Occupations.Name,
                                         DepartmentName = s.Departments.Name
                                     })
                                     .ToList();

Finally I get error:

Only parameterless constructors and initializers are supported in LINQ to Entities.

Solution form the this post:

Only parameterless constructors and initializers are supported in LINQ to Entities

is working but why my constructor doesn't work?

2
  • 1
    Isn't it obvious from the exception message (the word parameterless). Also this has been asked many times stackoverflow.com/…. Commented Jan 15, 2017 at 21:26
  • I know but I want to rewrite the parameters easier. Commented Jan 15, 2017 at 21:50

1 Answer 1

2

As other tools, Entity Framework creates proxies of your models on run-time, and these are emitted as derived classes of your models. Clearly, you can't expect a proxy generator to use a constructor with parameters to instantiate your model.

In summary: keep it simple, use the tool the way it's meant to be used: your entities should contain at least their parameterless constructor.

Consider using AutoMapper to keep things simple:

// If you go for the AutoMapper approach, you need no constructor 
// with parameters or factory method anymore!
List<Employee_ViewModel> item = contex.Employees.Where(w => w.IsActive == true && w.IsVisible == true)
                                     .Include(i => i.Departments)
                                     .Include(i => i.Occupations)
                                     .ProjectTo<EmployeeViewModel>()
                                     .ToList();

See AutoMapper's docs to queryable extensions to learn more about how to combine it with Entity Framework.

Sign up to request clarification or add additional context in comments.

4 Comments

I used solution with functions From, but return error: LINQ to Entities does not recognize the method 'MS.ViewModel.Employee_ViewModel From(MS.Models.Employees)' method, and this method cannot be translated into a store expression. What about performance, better use AutoMapper?
Adding ToList() before Select solving a problem. But is correct solution?
@18666 My first attemp was wrong. You're right, expression trees should be translatable to SQL and a custom factory isn't possible to be translated into SQL. See my updated answer on which I've thrown away the wrong part, and I've edited the AutoMapper approach.
@18666 As of your attemp of calling ToList and later Select, it's not a good idea, because usually you don't want to get your entire table in memory to do filters, projections and so on. Probably you want them to happen in the database.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.