Passing data from View Model to View









up vote
0
down vote

favorite












I need Your help.
I create a program in asp.net mvc. I wrote the model class and the ViewModel class



public class Student

public int StudentId get; set;
public string StudentName get; set;
public int IndexNumber get; set;

public ICollection<Course> Course get; set;

public class Course

public int CourseId get; set;
public string CoureName get; set;
public int NumberHours get; set;
public bool IsExam get; set;

public ICollection<Student> Student get; set;


public class ScheduleVM

public string StudentName get; set; // Student class
public int IndexNumber get; set; // Student class
public string CourseName get; set; // Course class




The ScheduleVM class does not exist in the context class, and I want to create a view that only returns the data from the ScheduleVM class. I wrote the Schedule controller manually and have a view. I do not know how to transfer some of this data to the database view using EF and Linq?
If anyone has any guide, please send me a link.



Edit:



View from ScheduleVM class:



 @model IEnumerable<StudentApp.Models.ScheduleVM>

<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.StudentName)
</th>
<th>
@Html.DisplayNameFor(model => model.IndexNumber)
</th>
<th>
@Html.DisplayNameFor(model => model.CoureName)
</th>
<th>
@Html.DisplayNameFor(model => model.NameInstructor)
</th>
<th>
@Html.DisplayNameFor(model => model.DepartmentName)
</th>
<th></th>
</tr>

@foreach (var item in Model)
<tr>
<td>
@Html.DisplayFor(modelItem => item.StudentName)
</td>
<td>
@Html.DisplayFor(modelItem => item.IndexNumber)
</td>
<td>
@Html.DisplayFor(modelItem => item.CoureName)
</td>
<td>
@Html.DisplayFor(modelItem => item.NameInstructor)
</td>
<td>
@Html.DisplayFor(modelItem => item.DepartmentName)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new /* id=item.PrimaryKey */ )

</table>


The foreach loop does not work, of course, because I do not have a model. I generated the view, but I removed the reference to the context class. Regarding the controller, I do not know how to get the data that I need.



Controller class:



public class ScheduleController : Controller


// GET: Schedule
public ActionResult Index()

List<ScheduleVM> ScheduleVMlist = new List<ScheduleVM>();

return View();




I have added data to the student and course table, and now I want to display the selected information, but I do not know how to extract this data from the database ?



public class ModelContext : DbContext

public ModelContext()
: base("name=ModelContext")


public DbSet<Student> Students get; set;
public DbSet<Course> Courses get; set;











share|improve this question



















  • 1




    Could you show us your Schedule controller and view code? thanks
    – D-Shih
    Nov 11 at 15:31










  • I edited my first post.
    – Antero00
    Nov 11 at 15:38






  • 2




    the Model is usually passed as a parameter to the Controller function. Here you only show the Model and the View... not the Controller code.
    – montewhizdoh
    Nov 11 at 15:48











  • I added code from controller class.
    – Antero00
    Nov 11 at 16:04










  • Are you using EF if yes could you show us your EF Context class?
    – D-Shih
    Nov 11 at 16:07














up vote
0
down vote

favorite












I need Your help.
I create a program in asp.net mvc. I wrote the model class and the ViewModel class



public class Student

public int StudentId get; set;
public string StudentName get; set;
public int IndexNumber get; set;

public ICollection<Course> Course get; set;

public class Course

public int CourseId get; set;
public string CoureName get; set;
public int NumberHours get; set;
public bool IsExam get; set;

public ICollection<Student> Student get; set;


public class ScheduleVM

public string StudentName get; set; // Student class
public int IndexNumber get; set; // Student class
public string CourseName get; set; // Course class




The ScheduleVM class does not exist in the context class, and I want to create a view that only returns the data from the ScheduleVM class. I wrote the Schedule controller manually and have a view. I do not know how to transfer some of this data to the database view using EF and Linq?
If anyone has any guide, please send me a link.



Edit:



View from ScheduleVM class:



 @model IEnumerable<StudentApp.Models.ScheduleVM>

<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.StudentName)
</th>
<th>
@Html.DisplayNameFor(model => model.IndexNumber)
</th>
<th>
@Html.DisplayNameFor(model => model.CoureName)
</th>
<th>
@Html.DisplayNameFor(model => model.NameInstructor)
</th>
<th>
@Html.DisplayNameFor(model => model.DepartmentName)
</th>
<th></th>
</tr>

@foreach (var item in Model)
<tr>
<td>
@Html.DisplayFor(modelItem => item.StudentName)
</td>
<td>
@Html.DisplayFor(modelItem => item.IndexNumber)
</td>
<td>
@Html.DisplayFor(modelItem => item.CoureName)
</td>
<td>
@Html.DisplayFor(modelItem => item.NameInstructor)
</td>
<td>
@Html.DisplayFor(modelItem => item.DepartmentName)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new /* id=item.PrimaryKey */ )

</table>


The foreach loop does not work, of course, because I do not have a model. I generated the view, but I removed the reference to the context class. Regarding the controller, I do not know how to get the data that I need.



Controller class:



public class ScheduleController : Controller


// GET: Schedule
public ActionResult Index()

List<ScheduleVM> ScheduleVMlist = new List<ScheduleVM>();

return View();




I have added data to the student and course table, and now I want to display the selected information, but I do not know how to extract this data from the database ?



public class ModelContext : DbContext

public ModelContext()
: base("name=ModelContext")


public DbSet<Student> Students get; set;
public DbSet<Course> Courses get; set;











share|improve this question



















  • 1




    Could you show us your Schedule controller and view code? thanks
    – D-Shih
    Nov 11 at 15:31










  • I edited my first post.
    – Antero00
    Nov 11 at 15:38






  • 2




    the Model is usually passed as a parameter to the Controller function. Here you only show the Model and the View... not the Controller code.
    – montewhizdoh
    Nov 11 at 15:48











  • I added code from controller class.
    – Antero00
    Nov 11 at 16:04










  • Are you using EF if yes could you show us your EF Context class?
    – D-Shih
    Nov 11 at 16:07












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I need Your help.
I create a program in asp.net mvc. I wrote the model class and the ViewModel class



public class Student

public int StudentId get; set;
public string StudentName get; set;
public int IndexNumber get; set;

public ICollection<Course> Course get; set;

public class Course

public int CourseId get; set;
public string CoureName get; set;
public int NumberHours get; set;
public bool IsExam get; set;

public ICollection<Student> Student get; set;


public class ScheduleVM

public string StudentName get; set; // Student class
public int IndexNumber get; set; // Student class
public string CourseName get; set; // Course class




The ScheduleVM class does not exist in the context class, and I want to create a view that only returns the data from the ScheduleVM class. I wrote the Schedule controller manually and have a view. I do not know how to transfer some of this data to the database view using EF and Linq?
If anyone has any guide, please send me a link.



Edit:



View from ScheduleVM class:



 @model IEnumerable<StudentApp.Models.ScheduleVM>

<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.StudentName)
</th>
<th>
@Html.DisplayNameFor(model => model.IndexNumber)
</th>
<th>
@Html.DisplayNameFor(model => model.CoureName)
</th>
<th>
@Html.DisplayNameFor(model => model.NameInstructor)
</th>
<th>
@Html.DisplayNameFor(model => model.DepartmentName)
</th>
<th></th>
</tr>

@foreach (var item in Model)
<tr>
<td>
@Html.DisplayFor(modelItem => item.StudentName)
</td>
<td>
@Html.DisplayFor(modelItem => item.IndexNumber)
</td>
<td>
@Html.DisplayFor(modelItem => item.CoureName)
</td>
<td>
@Html.DisplayFor(modelItem => item.NameInstructor)
</td>
<td>
@Html.DisplayFor(modelItem => item.DepartmentName)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new /* id=item.PrimaryKey */ )

</table>


The foreach loop does not work, of course, because I do not have a model. I generated the view, but I removed the reference to the context class. Regarding the controller, I do not know how to get the data that I need.



Controller class:



public class ScheduleController : Controller


// GET: Schedule
public ActionResult Index()

List<ScheduleVM> ScheduleVMlist = new List<ScheduleVM>();

return View();




I have added data to the student and course table, and now I want to display the selected information, but I do not know how to extract this data from the database ?



public class ModelContext : DbContext

public ModelContext()
: base("name=ModelContext")


public DbSet<Student> Students get; set;
public DbSet<Course> Courses get; set;











share|improve this question















I need Your help.
I create a program in asp.net mvc. I wrote the model class and the ViewModel class



public class Student

public int StudentId get; set;
public string StudentName get; set;
public int IndexNumber get; set;

public ICollection<Course> Course get; set;

public class Course

public int CourseId get; set;
public string CoureName get; set;
public int NumberHours get; set;
public bool IsExam get; set;

public ICollection<Student> Student get; set;


public class ScheduleVM

public string StudentName get; set; // Student class
public int IndexNumber get; set; // Student class
public string CourseName get; set; // Course class




The ScheduleVM class does not exist in the context class, and I want to create a view that only returns the data from the ScheduleVM class. I wrote the Schedule controller manually and have a view. I do not know how to transfer some of this data to the database view using EF and Linq?
If anyone has any guide, please send me a link.



Edit:



View from ScheduleVM class:



 @model IEnumerable<StudentApp.Models.ScheduleVM>

<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.StudentName)
</th>
<th>
@Html.DisplayNameFor(model => model.IndexNumber)
</th>
<th>
@Html.DisplayNameFor(model => model.CoureName)
</th>
<th>
@Html.DisplayNameFor(model => model.NameInstructor)
</th>
<th>
@Html.DisplayNameFor(model => model.DepartmentName)
</th>
<th></th>
</tr>

@foreach (var item in Model)
<tr>
<td>
@Html.DisplayFor(modelItem => item.StudentName)
</td>
<td>
@Html.DisplayFor(modelItem => item.IndexNumber)
</td>
<td>
@Html.DisplayFor(modelItem => item.CoureName)
</td>
<td>
@Html.DisplayFor(modelItem => item.NameInstructor)
</td>
<td>
@Html.DisplayFor(modelItem => item.DepartmentName)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new /* id=item.PrimaryKey */ )

</table>


The foreach loop does not work, of course, because I do not have a model. I generated the view, but I removed the reference to the context class. Regarding the controller, I do not know how to get the data that I need.



Controller class:



public class ScheduleController : Controller


// GET: Schedule
public ActionResult Index()

List<ScheduleVM> ScheduleVMlist = new List<ScheduleVM>();

return View();




I have added data to the student and course table, and now I want to display the selected information, but I do not know how to extract this data from the database ?



public class ModelContext : DbContext

public ModelContext()
: base("name=ModelContext")


public DbSet<Student> Students get; set;
public DbSet<Course> Courses get; set;








c# asp.net-mvc entity-framework linq






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 11 at 16:08

























asked Nov 11 at 15:25









Antero00

1616




1616







  • 1




    Could you show us your Schedule controller and view code? thanks
    – D-Shih
    Nov 11 at 15:31










  • I edited my first post.
    – Antero00
    Nov 11 at 15:38






  • 2




    the Model is usually passed as a parameter to the Controller function. Here you only show the Model and the View... not the Controller code.
    – montewhizdoh
    Nov 11 at 15:48











  • I added code from controller class.
    – Antero00
    Nov 11 at 16:04










  • Are you using EF if yes could you show us your EF Context class?
    – D-Shih
    Nov 11 at 16:07












  • 1




    Could you show us your Schedule controller and view code? thanks
    – D-Shih
    Nov 11 at 15:31










  • I edited my first post.
    – Antero00
    Nov 11 at 15:38






  • 2




    the Model is usually passed as a parameter to the Controller function. Here you only show the Model and the View... not the Controller code.
    – montewhizdoh
    Nov 11 at 15:48











  • I added code from controller class.
    – Antero00
    Nov 11 at 16:04










  • Are you using EF if yes could you show us your EF Context class?
    – D-Shih
    Nov 11 at 16:07







1




1




Could you show us your Schedule controller and view code? thanks
– D-Shih
Nov 11 at 15:31




Could you show us your Schedule controller and view code? thanks
– D-Shih
Nov 11 at 15:31












I edited my first post.
– Antero00
Nov 11 at 15:38




I edited my first post.
– Antero00
Nov 11 at 15:38




2




2




the Model is usually passed as a parameter to the Controller function. Here you only show the Model and the View... not the Controller code.
– montewhizdoh
Nov 11 at 15:48





the Model is usually passed as a parameter to the Controller function. Here you only show the Model and the View... not the Controller code.
– montewhizdoh
Nov 11 at 15:48













I added code from controller class.
– Antero00
Nov 11 at 16:04




I added code from controller class.
– Antero00
Nov 11 at 16:04












Are you using EF if yes could you show us your EF Context class?
– D-Shih
Nov 11 at 16:07




Are you using EF if yes could you show us your EF Context class?
– D-Shih
Nov 11 at 16:07












1 Answer
1






active

oldest

votes

















up vote
0
down vote













An efficient way is to compose your query across the entities, then use .Select() to populate the relevant view models. You can populate the view models yourself, or leverage a library like Automapper to help with more complex or larger view models. AutoMapper now offers a ProjectTo extension method that plays nice with EF and IQueryable.



So for example if you had a search that looked to list courses with a name starting with a provided criteria:



This assumes that you want the students and course information based on the course name. Students have a Courses collection, but courses do not have a Students collection.



using (var context = new MyContext())

var courseIds = context.Courses
.Where(c => c.CourseName.StartsWith(searchText))
.ToList();

var query = context.Students
.Where(s => s.Courses.Any(c => courseIds.Contains(c.CourseId)));



Now at this point we have an IQueryable which should give us all students that have at least 1 matching course. I split off the course search to retrieve just a list of matching course IDs since these will be easier to match against than embedding that criteria into the following queries. These can be combined, but if you have several different criteria it may be easier to follow by using those to identify IDs for following queries.



Nothing has been run against the database. The next step will be that we want to flatten the result to list the student details with just the matching courses for example. If we searched for "Math" we want to return just the course, or courses for each student that match that pattern. A student may be taking "Math 100" and "Math 200"



using (var context = new MyContext())

var courseIds = context.Courses
.Where(c => c.CourseName.StartsWith(searchText))
.ToList();

var query = context.Students
.Where(s => s.Courses.Any(c => courseIds.Contains(c.CourseId)));

var viewModels = query.SelectMany( s => s.Courses.Where(c => courseIds.Contains(c.CourseId))
.Select(c => new ScheduleVM

StudentName = s.StudentName,
IndexNumber = s.IndexNumber,
CourseName = c.CourseName
)).ToList()



This can be condensed to a single Linq query, but I kept it separated to make it a bit easier to cover. The first "query" retrieved our students that had matching courses, but at that point that student's course list would be all courses the student is taking. In this example we only want to list matching courses. So from Student we do a SelectMany to get course details, and use a Where condition to only retrieve the courses with the matching IDs. From there we do a .Select against those matching courses. Because we are still within the scope of the SelectMany against the student, we can still access "s" which represents the current student. We "Select" our our view model, providing the relevant columns from Student ("s") and Course ("c"). The ToList at the end is what will actually trigger the SQL to run. EF will compose a query that filters the data, then returns just the 3 columns we need to populate the view model.



Hopefully that gives you some ideas on how to leverage EF to populate the data you want to feed to your view. I would recommend including IDs in your view model, even if you don't display them, because that will be useful for retrieving the relevant student and/or course for any actions you want to take based on this data.






share|improve this answer




















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53250194%2fpassing-data-from-view-model-to-view%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    An efficient way is to compose your query across the entities, then use .Select() to populate the relevant view models. You can populate the view models yourself, or leverage a library like Automapper to help with more complex or larger view models. AutoMapper now offers a ProjectTo extension method that plays nice with EF and IQueryable.



    So for example if you had a search that looked to list courses with a name starting with a provided criteria:



    This assumes that you want the students and course information based on the course name. Students have a Courses collection, but courses do not have a Students collection.



    using (var context = new MyContext())

    var courseIds = context.Courses
    .Where(c => c.CourseName.StartsWith(searchText))
    .ToList();

    var query = context.Students
    .Where(s => s.Courses.Any(c => courseIds.Contains(c.CourseId)));



    Now at this point we have an IQueryable which should give us all students that have at least 1 matching course. I split off the course search to retrieve just a list of matching course IDs since these will be easier to match against than embedding that criteria into the following queries. These can be combined, but if you have several different criteria it may be easier to follow by using those to identify IDs for following queries.



    Nothing has been run against the database. The next step will be that we want to flatten the result to list the student details with just the matching courses for example. If we searched for "Math" we want to return just the course, or courses for each student that match that pattern. A student may be taking "Math 100" and "Math 200"



    using (var context = new MyContext())

    var courseIds = context.Courses
    .Where(c => c.CourseName.StartsWith(searchText))
    .ToList();

    var query = context.Students
    .Where(s => s.Courses.Any(c => courseIds.Contains(c.CourseId)));

    var viewModels = query.SelectMany( s => s.Courses.Where(c => courseIds.Contains(c.CourseId))
    .Select(c => new ScheduleVM

    StudentName = s.StudentName,
    IndexNumber = s.IndexNumber,
    CourseName = c.CourseName
    )).ToList()



    This can be condensed to a single Linq query, but I kept it separated to make it a bit easier to cover. The first "query" retrieved our students that had matching courses, but at that point that student's course list would be all courses the student is taking. In this example we only want to list matching courses. So from Student we do a SelectMany to get course details, and use a Where condition to only retrieve the courses with the matching IDs. From there we do a .Select against those matching courses. Because we are still within the scope of the SelectMany against the student, we can still access "s" which represents the current student. We "Select" our our view model, providing the relevant columns from Student ("s") and Course ("c"). The ToList at the end is what will actually trigger the SQL to run. EF will compose a query that filters the data, then returns just the 3 columns we need to populate the view model.



    Hopefully that gives you some ideas on how to leverage EF to populate the data you want to feed to your view. I would recommend including IDs in your view model, even if you don't display them, because that will be useful for retrieving the relevant student and/or course for any actions you want to take based on this data.






    share|improve this answer
























      up vote
      0
      down vote













      An efficient way is to compose your query across the entities, then use .Select() to populate the relevant view models. You can populate the view models yourself, or leverage a library like Automapper to help with more complex or larger view models. AutoMapper now offers a ProjectTo extension method that plays nice with EF and IQueryable.



      So for example if you had a search that looked to list courses with a name starting with a provided criteria:



      This assumes that you want the students and course information based on the course name. Students have a Courses collection, but courses do not have a Students collection.



      using (var context = new MyContext())

      var courseIds = context.Courses
      .Where(c => c.CourseName.StartsWith(searchText))
      .ToList();

      var query = context.Students
      .Where(s => s.Courses.Any(c => courseIds.Contains(c.CourseId)));



      Now at this point we have an IQueryable which should give us all students that have at least 1 matching course. I split off the course search to retrieve just a list of matching course IDs since these will be easier to match against than embedding that criteria into the following queries. These can be combined, but if you have several different criteria it may be easier to follow by using those to identify IDs for following queries.



      Nothing has been run against the database. The next step will be that we want to flatten the result to list the student details with just the matching courses for example. If we searched for "Math" we want to return just the course, or courses for each student that match that pattern. A student may be taking "Math 100" and "Math 200"



      using (var context = new MyContext())

      var courseIds = context.Courses
      .Where(c => c.CourseName.StartsWith(searchText))
      .ToList();

      var query = context.Students
      .Where(s => s.Courses.Any(c => courseIds.Contains(c.CourseId)));

      var viewModels = query.SelectMany( s => s.Courses.Where(c => courseIds.Contains(c.CourseId))
      .Select(c => new ScheduleVM

      StudentName = s.StudentName,
      IndexNumber = s.IndexNumber,
      CourseName = c.CourseName
      )).ToList()



      This can be condensed to a single Linq query, but I kept it separated to make it a bit easier to cover. The first "query" retrieved our students that had matching courses, but at that point that student's course list would be all courses the student is taking. In this example we only want to list matching courses. So from Student we do a SelectMany to get course details, and use a Where condition to only retrieve the courses with the matching IDs. From there we do a .Select against those matching courses. Because we are still within the scope of the SelectMany against the student, we can still access "s" which represents the current student. We "Select" our our view model, providing the relevant columns from Student ("s") and Course ("c"). The ToList at the end is what will actually trigger the SQL to run. EF will compose a query that filters the data, then returns just the 3 columns we need to populate the view model.



      Hopefully that gives you some ideas on how to leverage EF to populate the data you want to feed to your view. I would recommend including IDs in your view model, even if you don't display them, because that will be useful for retrieving the relevant student and/or course for any actions you want to take based on this data.






      share|improve this answer






















        up vote
        0
        down vote










        up vote
        0
        down vote









        An efficient way is to compose your query across the entities, then use .Select() to populate the relevant view models. You can populate the view models yourself, or leverage a library like Automapper to help with more complex or larger view models. AutoMapper now offers a ProjectTo extension method that plays nice with EF and IQueryable.



        So for example if you had a search that looked to list courses with a name starting with a provided criteria:



        This assumes that you want the students and course information based on the course name. Students have a Courses collection, but courses do not have a Students collection.



        using (var context = new MyContext())

        var courseIds = context.Courses
        .Where(c => c.CourseName.StartsWith(searchText))
        .ToList();

        var query = context.Students
        .Where(s => s.Courses.Any(c => courseIds.Contains(c.CourseId)));



        Now at this point we have an IQueryable which should give us all students that have at least 1 matching course. I split off the course search to retrieve just a list of matching course IDs since these will be easier to match against than embedding that criteria into the following queries. These can be combined, but if you have several different criteria it may be easier to follow by using those to identify IDs for following queries.



        Nothing has been run against the database. The next step will be that we want to flatten the result to list the student details with just the matching courses for example. If we searched for "Math" we want to return just the course, or courses for each student that match that pattern. A student may be taking "Math 100" and "Math 200"



        using (var context = new MyContext())

        var courseIds = context.Courses
        .Where(c => c.CourseName.StartsWith(searchText))
        .ToList();

        var query = context.Students
        .Where(s => s.Courses.Any(c => courseIds.Contains(c.CourseId)));

        var viewModels = query.SelectMany( s => s.Courses.Where(c => courseIds.Contains(c.CourseId))
        .Select(c => new ScheduleVM

        StudentName = s.StudentName,
        IndexNumber = s.IndexNumber,
        CourseName = c.CourseName
        )).ToList()



        This can be condensed to a single Linq query, but I kept it separated to make it a bit easier to cover. The first "query" retrieved our students that had matching courses, but at that point that student's course list would be all courses the student is taking. In this example we only want to list matching courses. So from Student we do a SelectMany to get course details, and use a Where condition to only retrieve the courses with the matching IDs. From there we do a .Select against those matching courses. Because we are still within the scope of the SelectMany against the student, we can still access "s" which represents the current student. We "Select" our our view model, providing the relevant columns from Student ("s") and Course ("c"). The ToList at the end is what will actually trigger the SQL to run. EF will compose a query that filters the data, then returns just the 3 columns we need to populate the view model.



        Hopefully that gives you some ideas on how to leverage EF to populate the data you want to feed to your view. I would recommend including IDs in your view model, even if you don't display them, because that will be useful for retrieving the relevant student and/or course for any actions you want to take based on this data.






        share|improve this answer












        An efficient way is to compose your query across the entities, then use .Select() to populate the relevant view models. You can populate the view models yourself, or leverage a library like Automapper to help with more complex or larger view models. AutoMapper now offers a ProjectTo extension method that plays nice with EF and IQueryable.



        So for example if you had a search that looked to list courses with a name starting with a provided criteria:



        This assumes that you want the students and course information based on the course name. Students have a Courses collection, but courses do not have a Students collection.



        using (var context = new MyContext())

        var courseIds = context.Courses
        .Where(c => c.CourseName.StartsWith(searchText))
        .ToList();

        var query = context.Students
        .Where(s => s.Courses.Any(c => courseIds.Contains(c.CourseId)));



        Now at this point we have an IQueryable which should give us all students that have at least 1 matching course. I split off the course search to retrieve just a list of matching course IDs since these will be easier to match against than embedding that criteria into the following queries. These can be combined, but if you have several different criteria it may be easier to follow by using those to identify IDs for following queries.



        Nothing has been run against the database. The next step will be that we want to flatten the result to list the student details with just the matching courses for example. If we searched for "Math" we want to return just the course, or courses for each student that match that pattern. A student may be taking "Math 100" and "Math 200"



        using (var context = new MyContext())

        var courseIds = context.Courses
        .Where(c => c.CourseName.StartsWith(searchText))
        .ToList();

        var query = context.Students
        .Where(s => s.Courses.Any(c => courseIds.Contains(c.CourseId)));

        var viewModels = query.SelectMany( s => s.Courses.Where(c => courseIds.Contains(c.CourseId))
        .Select(c => new ScheduleVM

        StudentName = s.StudentName,
        IndexNumber = s.IndexNumber,
        CourseName = c.CourseName
        )).ToList()



        This can be condensed to a single Linq query, but I kept it separated to make it a bit easier to cover. The first "query" retrieved our students that had matching courses, but at that point that student's course list would be all courses the student is taking. In this example we only want to list matching courses. So from Student we do a SelectMany to get course details, and use a Where condition to only retrieve the courses with the matching IDs. From there we do a .Select against those matching courses. Because we are still within the scope of the SelectMany against the student, we can still access "s" which represents the current student. We "Select" our our view model, providing the relevant columns from Student ("s") and Course ("c"). The ToList at the end is what will actually trigger the SQL to run. EF will compose a query that filters the data, then returns just the 3 columns we need to populate the view model.



        Hopefully that gives you some ideas on how to leverage EF to populate the data you want to feed to your view. I would recommend including IDs in your view model, even if you don't display them, because that will be useful for retrieving the relevant student and/or course for any actions you want to take based on this data.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 11 at 22:15









        Steve Py

        5,15011017




        5,15011017



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53250194%2fpassing-data-from-view-model-to-view%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Barbados

            How to read a connectionString WITH PROVIDER in .NET Core?

            Node.js Script on GitHub Pages or Amazon S3