Как получить результаты в View из 3 таблиц в MVC - PullRequest
0 голосов
/ 20 марта 2019

У меня есть 3 Связанные таблицы, Table1 => Table2 => Table3 Отношения как этот тип.

У меня есть данные из Таблицы1 и Таблицы2, потому что у меня есть модель для отображения из Таблицы1, теперь моя проблема в Таблице3, я не могу получить данные для отображения. Мне нужно показать данные в деталях, и мой проект предназначен для опросов.

  1. Таблица1 = Вопросы (ключ QID)
  2. Table2 = Варианты ответов (ключ ANID, а q_ID - ключ к Вопросам)
  3. Таблица3 = Результаты (Подсчет голосов) (ключ - RID, а ans_ID - ключ для AnswerOption)

Контроллер является кодом по умолчанию:

 public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }



            Questions questions= db.Questions.Find(id);
            if (questions== null)
            {
                return HttpNotFound();
            }




            return View(questions);
        }

ПОСМОТРЕТЬ КОД:

 @foreach (var item in Model.Answers)
        {

            if (item != null)
            {
        <tr>
            <td>
                @Html.DisplayFor(x => item.AnswerName)
            </td>
            <td>
                @Html.DisplayFor(x => item.Results.Result)
            </td>

        </tr>
            }

МОДЕЛЬНЫЕ ВОПРОСЫ:

public class Questions
    {
        public Questions()
        {
            Answers= new HashSet<Answers>();

        }
        [Key]
        public  int QID { get; set; }
        public string Prasanje { get; set; }
        public bool pubOdg { get; set; }
        public int? avtor { get; set; }

        public virtual ICollection<Answers> Answers { get; set; }

       [ForeignKey("avtor")]
        public virtual tbl_useri tbl_useri { get; set; }

    }

ОТВЕТЫ МОДЕЛИ:

 public Answers()
        {
            Results= new HashSet<Results>();
        }

        [Key]
        public int ANID{ get; set; }

        public int q_ID{ get; set; }


        public string Odgovor { get; set; }
        public string kreator { get; set; }
        public int? rCount { get; set; }

        [ForeignKey("q_ID")]
        public virtual Questions Questions{ get; set; }

        public virtual ICollection<Results> Results{ get; set; }

РЕЗУЛЬТАТЫ МОДЕЛИ:

 public class Results
    {
        [Key]
        public int RID{ get; set; }
        public int ans_ID{ get; set; }
        public int Result{ get; set; }


        [ForeignKey("ans_ID")]
        public virtual Answers Answers { get; set; }

    }

1 Ответ

0 голосов
/ 21 марта 2019

Я начну с некоторых определений:

  • A view-model - это тип, который представляет данные, относящиеся к конкретному отображаемому представлению. Действие контроллера должно создать этот объект и заполнить его загруженными данными, а затем передать его представлению.
    • Это лежит в основе разделения проблем в ASP.NET MVC и ASP.NET Core и является общим шаблоном проектирования во всех современных (после 2005 года) средах веб-программирования.
    • Сравните это со старым школьным программированием на PHP / CGI / Classic ASP, где вы бы смешали код базы данных с HTML.
    • В веб-программировании View-Model, как правило, является ненаблюдаемым, неизменным и эфемерным объектом, который длится только в течение жизни HTTP-запроса. В то время как в настольном программировании (например, WPF, UWP XAML и т. Д.) Модель представления обычно наблюдаема, изменчива и долговечна ).
  • A model (отличный от view-model ) или entity class - это объект, который представляет данные из вашей базы данных резервного хранилища. (Не обращайте внимания на тот факт, что Razor использует ключевое слово @model для обозначения модели представления).

(Я разочарован и раздражен тем, что большинство учебников начального уровня для ASP.NET MVC и ASP.NET Core по-прежнему знакомят пользователей с анти-паттерном использования типов сущностей Entity Framework в качестве моделей представления. Эти учебники должны научить читателей использовать отдельные модели представлений, чтобы избежать введения читателей по неправильному пути и возможной путаницы, как этот OP. Использование сущностей EF в качестве моделей представлений также приводит к проблемам безопасности, поскольку позволяет злонамеренному пользователю сбросить пароли других пользователей (например) если неадекватная проверка входных запросов (для этого, например, [BindNever]). Моя точка зрения: просто не .)

Вернуться по теме:

Если это одностороннее представление (т. Е. Вы показываете данные только из вашей базы данных, не позволяя пользователю редактировать эти данные в <form>), тогда определите новый класс в качестве модели представления и заполните его данные вашей сущности как свойства.

В вашем случае ваше действие контроллера равно QuestionsController::Details, поэтому я бы получил следующее:

public class DetailsViewModel
{
    // One-way members:

    [BindNever]
    public String PageTitle { get; internal set; }

    public Question TheQuestion  { get; internal set; }

    public List<Answer> TheAnswers { get; internal set; }

    // Two-way members:

    // (you don't have any forms, so this area is empty)
}

Затем измените действие вашего контроллера, чтобы создать, заполнить и вернуть этот тип модели представления:

public async IActionResult Details(Int32? id)
{
    if( id == null ) return this.NotFound();

    Question question = await this.db.Questions.SingleOrDefaultAsync( id.Value );
    if( question == null ) return this.NotFound();

    DetailsViewModel vm = new DetailsViewModel()
    {
        PageTitle = "Details for " + question.Title,
        TheQuestion = question,
        TheAnswers = await this.db.Answers.Where( q => a.Question == question ).ToListAsync()
    };

    return this.View( model: vm );
}

И измените свой вид Razor, чтобы использовать эту модель:

@model DetailsViewModel

<html>
<head>
<title>@Model.PageTitle</title>
</head>
<body>

<h2>Question</h2>

<p>@Model.TheQuestion.QuestionText</p>

<h2>Answers</h2>

@foreach( Answer ans in this.Model.TheAnswers )
{
<h3>Answer @ans.Name</h3>

    @foreach( Result result in ans.Results )
    {
<h3>@result.Name</h3>
    }
}

</body>
</html>

Если вы хотите разрешить пользователям редактировать данные в POST в <form>, то вам нужно будет по существу определить новые классы для каждой строки таблицы, которую вы хотите, чтобы пользователи могли редактировать. Но это выходит за рамки вашего первоначального вопроса, но поиск в Интернете «ASP.NET MVC модель привязки» для получения дополнительной информации.

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