Передача данных из View Model в View - PullRequest
0 голосов
/ 11 ноября 2018

Мне нужна твоя помощь. Я создаю программу в asp.net MVC. Я написал класс модели и класс ViewModel

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

}

Класс ScheduleVM не существует в классе контекста, и я хочу создать представление, которое возвращает только данные из класса ScheduleVM. Я написал контроллер расписания вручную и у меня есть представление. Я не знаю, как перенести некоторые из этих данных в представление базы данных с помощью EF и Linq? Если у кого-нибудь есть руководство, пришлите мне ссылку.

Edit:

Вид из класса ScheduleVM:

    @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 */ }) |
            @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
            @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
        </td>
    </tr>
}

</table>

Цикл foreach не работает, конечно, потому что у меня нет модели. Я сгенерировал представление, но удалил ссылку на класс контекста. Что касается контроллера, я не знаю, как получить данные, которые мне нужны.

Класс контроллера:

public class ScheduleController : Controller
{

    // GET: Schedule
    public ActionResult Index()
    {
        List<ScheduleVM> ScheduleVMlist = new List<ScheduleVM>();

        return View();
    }
}

Я добавил данные в таблицу студентов и курсов, и теперь я хочу отобразить выбранную информацию, но я не знаю, как извлечь эти данные из базы данных?

public class ModelContext : DbContext
{
    public ModelContext()
        : base("name=ModelContext")
    {}

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

}

1 Ответ

0 голосов
/ 12 ноября 2018

Эффективным способом является составление запроса по всем сущностям, а затем использование .Select() для заполнения соответствующих моделей представлений. Вы можете заполнить модели представлений самостоятельно или использовать библиотеку, например Automapper, чтобы помочь с более сложными или более крупными моделями представлений. AutoMapper теперь предлагает метод расширения ProjectTo, который хорошо работает с EF и IQueryable.

Так, например, если у вас был поиск, который просматривал список курсов с названием, начинающимся с указанных критериев:

Это предполагает, что вы хотите, чтобы студенты и информация о курсе основывались на названии курса. У студентов есть коллекция курсов, но у курсов нет коллекции студентов.

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)));
}

Теперь у нас есть IQueryable, который должен дать нам всех студентов, у которых есть хотя бы 1 соответствующий курс. Я отделил поиск курса, чтобы получить только список совпадающих идентификаторов курса, поскольку с ними будет легче сопоставить, чем встраивать этот критерий в следующие запросы. Они могут быть объединены, но если у вас есть несколько различных критериев, им будет легче следовать, используя их для идентификации идентификаторов для следующих запросов.

Ничего не было запущено для базы данных. Следующим шагом будет то, что мы хотим сгладить результат, чтобы перечислить сведения об ученике, например, только с соответствующими курсами. Если мы искали «Математика», мы хотим вернуть только курс или курсы для каждого ученика, которые соответствуют этому шаблону. Студент может принимать "Math 100" и "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()
}

Это может быть сведено к одному запросу Linq, но я держал его отдельно, чтобы его было легче охватить. Первый «запрос» извлекал наших студентов, у которых были совпадающие курсы, но в этот момент список курсов ученика был бы всеми курсами, которые студент посещает. В этом примере мы хотим перечислить только соответствующие курсы. Таким образом, от Студента мы делаем SelectMany, чтобы получить детали курса, и используем условие Where, чтобы только извлечь курсы с соответствующими идентификаторами. Оттуда мы делаем. Выбор против этих соответствующих курсов. Поскольку мы все еще в рамках SelectMany против студента, мы все еще можем получить доступ к «s», который представляет текущего студента. Мы "выбираем" нашу модель представления, предоставляя соответствующие столбцы из Student ("s") и Course ("c"). ToList в конце - это то, что фактически запускает SQL. EF создаст запрос, который фильтрует данные, а затем возвращает только 3 столбца, которые нам нужны для заполнения модели представления.

Надеюсь, это даст вам некоторые идеи о том, как использовать EF для заполнения данных, которые вы хотите передать в ваше представление. Я бы порекомендовал включить идентификаторы в модель представления, даже если вы их не отображаете, поскольку это будет полезно для извлечения соответствующего студента и / или курса для любых действий, которые вы хотите предпринять на основе этих данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...