0

First of all please be sure that none of the solution on stackoverflow has not solved my problem (maybe it is caused from Entity Framework 6). I have 3 entities: Student, City and Region as below:

Entities:

public class Student
{
    public int ID { get; set; }

    public string Course { get; set; }  

    public int CityID { get; set; }

    public virtual City City { get; set; }
}


public class City
{
    public int ID { get; set; }        

    public string Name { get; set; }

    public int RegionID { get; set; }

    public virtual Region Region { get; set; }

    public virtual ICollection<Student> Students { get; set; }    
}


public class Region
{
    public int ID { get; set; }

    public string Name { get; set; }

    public virtual ICollection<City> Cities { get; set; } 
}


Controller:

public ActionResult Index_Read([DataSourceRequest] DataSourceRequest request)
    {
        var dataContext = repository.Students;
        var students = dataContext.ToDataSourceResult(request, m => new 
        {
            ID = m.ID,
            Course = m.Course,

            City = m.City.Name, //I can get City name and show it in View.
            MyRegionName = m.City.Region.Name //I can get region name and assign it to 
//"MyRegionName" parameter in JSON. However in View I cannot get it using "MyRegionName" paremeter  
        });           

        return Json(students, JsonRequestBehavior.AllowGet);
    }


View:

@model IEnumerable<Student>


@(Html.Kendo().Grid<Student>()
    .Name("Grid")
    .Columns(columns =>
    {
        columns.Bound(m => m.ID);
        columns.Bound(m => m.Course);
        columns.Bound(m => m.City);
        columns.Bound(m => m.MyRegionName);
    })
    .Pageable()
    .Sortable()
    .Filterable()
    .Scrollable()
    .Groupable()    
    .DataSource(dataSource => dataSource
        .Ajax()
        .Read(read => read.Action("Index_Read", "Student"))
    )        
)

Here is the point that may cause the problem in the Controller and View:

City = m.City.Name, //I can get City name and show it in View.
MyRegionName = m.City.Region.Name //I can get region name and assign it to the  "MyRegionName" parameter in JSON. However in View I cannot get it using "MyRegionName" paremeter.

May it be related to that there is City parameter in the Student entity. But there is no MyRegionName property in the City entity.

Jack
  • 1
  • 21
  • 118
  • 236
  • 1
    I'm sorry if this is dumb question but in your controller you return `multipliers` which I can't find on the scope and you are doing nothing with `students`. Why that ? – DontVoteMeDown Feb 05 '15 at 10:00
  • Sorry, I updated the names in order to simplify. Now it is OK, I updated as student. Have a look at again please? Thanks in advance.. – Jack Feb 05 '15 at 11:38
  • And what is `ToDataSourceResult` ? Can you post its code? – DontVoteMeDown Feb 05 '15 at 12:12
  • The ToDataSourceResult method uses the DataSourceRequest parameter and LINQ expressions to page, sort, filter and group your data. The JSON response of the action method will contain only a single page of data. The grid will be bound to that data. If your data is IQueryable returned by a LINQ-enabled provider (Entity Framework, LINQ to SQL, Telerik OpenAccess, NHibernate or other) the LINQ expressions created by the ToDataSourceResult method will be converted to SQL and executed by the database server. More info: http://docs.telerik.com/kendo-ui/aspnet-mvc/helpers/grid/ajax-binding – Jack Feb 05 '15 at 13:43

1 Answers1

1

In "Index_Read" method you are creating "IEnumerable of object" i.e. students which is not of "IEnumerable of Student" type. But in view you have binded your grid to "IEnumerable of Student". Since "Student" class doesn't contain "MyRegionName" property that's why you are facing issue.

Try something like this:

public ActionResult Index_Read([DataSourceRequest] DataSourceRequest request)
    {
        var dataContext = repository.Students;
        var students = dataContext.ToDataSourceResult(request, m => new StudentViewModel
        {
            ID = m.ID,
            Course = m.Course,
            CityName = m.City.Name, 
            RegionName = m.City.Region.Name 
        });           
        return Json(students, JsonRequestBehavior.AllowGet);
    }

public class StudentViewModel
{
    public int ID { get; set; }
    public string Course { get; set; }
    public string CityName { get; set; }
    public string RegionName { get; set; }
}

In View:

@model IEnumerable<StudentViewModel>

@(Html.Kendo().Grid<StudentViewModel>()
    .Name("Grid")
    .Columns(columns =>
    {
        columns.Bound(m => m.ID);
        columns.Bound(m => m.Course);
        columns.Bound(m => m.CityName);
        columns.Bound(m => m.RegionName);
    })
    .Pageable()
    .Sortable()
    .Filterable()
    .Scrollable()
    .Groupable()    
    .DataSource(dataSource => dataSource
        .Ajax()
        .Read(read => read.Action("Index_Read", "Student"))
    )        
)
adhishspn
  • 99
  • 1
  • 2
  • 7
  • Thanks a lot for your reply and nice explanation. you are right, I use Student class as you type. However, for this time I encountered the following error: # ERROR 1 # m => new Multiplier ("Cannot convert lambda expression to type 'System.Web.Mvc.ModelStateDictionary' because it is not a delegate type ...") # ERROR 2 # City.Region.Name = m.City.Region.Name (Invalid initializer member declarator) – Jack Feb 06 '15 at 07:52
  • 1
    I did silly error earlier (i.e. was trying to access complex object property but actually we can't access complex object properties in a class initializer) . I have modified above code, it should work now. – adhishspn Feb 06 '15 at 17:45
  • Thanks for reply. Actually I have used viewmodel as your last update. The only thing I wonder is that: Should we only use the necessary properties on StudentViewModel? I meant for example there are 20 properties in Student entity but we need 5 of them . In that case I think we only include these 5 properties in StudentViewModel instead of all of the 30 properties? Could you clarify a little bit please? – Jack Feb 06 '15 at 20:52
  • 1
    In view model we just include those properties which are required on view. So in your case include only 5 properties. More information on view models you can get [here](http://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc). Also please mark my last update as answer :) – adhishspn Feb 07 '15 at 13:14
  • Thanks for clarifying. Of course I marked as answer :) – Jack Feb 07 '15 at 22:51