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?

Community
  • 1
  • 1
18666
  • 125
  • 1
  • 18
  • 1
    Isn't it obvious from the exception message (the word **parameterless**). Also this has been asked many times http://stackoverflow.com/search?q=Only+parameterless+constructors+and+initializers+are+supported+in+LINQ+to+Entities. – Ivan Stoev Jan 15 '17 at 21:26
  • I know but I want to rewrite the parameters easier. – 18666 Jan 15 '17 at 21:50

1 Answers1

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.

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
  • 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? – 18666 Jan 15 '17 at 21:14
  • Adding ToList() before Select solving a problem. But is correct solution? – 18666 Jan 15 '17 at 21:48
  • 1
    @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**. – Matías Fidemraizer Jan 15 '17 at 22:10
  • @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. – Matías Fidemraizer Jan 15 '17 at 22:12