Search code examples
c#entity-frameworkviewmodelcode-first

Assign the result of Navigation Property to View Model


Here is my database schema:-

public class Department
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Employee> Employee_Id { get; set; }
}

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public long Salary { get; set; }
    public string Gender { get; set; }
    public virtual Department Department_Id { get; set; }
}

According to my research its a good practice to use View Models so I usually create my model with this kind of queries:-

var v = edm.Departments.Select(x => new departmentViewModel { Name = x.Name });
return v.ToList();

Now I like to add the benefit of Navigation Property into my code. Problem is its not useful for me if I cant assign the result to my View Model. If I try to access to a Department through a Employee I cant access to .Select() statement.

var v = edm.Employees.Where(x => x.Id == 1).FirstOrDefault().Department_Id. //Ops!!!

In above statement I can access to Id and Name but .Select() is inaccessible.

I can ignore Navigation Property and break my query into two queries and achieve what I want. But I'm asking how am I be able to to this with Navigation Property? Am I just misunderstanding the usage of it?


Solution

  • I found that in fact in my schema there is no Navigation Property. To have a Navigation Property you must have Constructor in your classes and ForeignKey that refer to that constructor.

    public class Department
    {
        public Department(){} //needed constructor
    
        public int Id { get; set; }
        public string Name { get; set; }
    
        [ForeignKey("Employee")]
        public int Employee_Id;
        public virtual ICollection<Employee> Employee { get; set; }
    }
    
    public class Employee
    {
        public Employee(){} //needed constructor
    
        public int Id { get; set; }
        public string Name { get; set; }
        public long Salary { get; set; }
        public string Gender { get; set; }
    
        [ForeignKey("Department")]
        public int Department_Id;
        public virtual Department Department { get; set; }
    }
    

    Now I can access to Department through Employee in a standard way but .Select() statement is still inaccessible. That doesn't really matter, I found that I can copy the result into View Model in next line without .Select() statement.

    var e = edm.Employees.Where(x => x.Id == 1).FirstOrDefault().Department; //.select() is still inaccessible
    departmentViewModel department = new departmentViewModel() { Id = e.Id, Name = e.Name };//but I could copy the result into my View Model here