Не можете получить доступ к таблице составного ключа через представление, чтобы ввести данные или назначить правильный первичный ключ в этой таблице? - PullRequest
0 голосов
/ 01 сентября 2018

Я пытаюсь разработать приложение ASP.NET MVC с использованием C # и EF с подходом, основанным на коде.

У меня есть два класса Actors и Movies, которые имеют отношения «многие ко многим» (Actor может быть во многих Movies, Movie может иметь много Actors).

Все работает правильно, но я не могу получить доступ к промежуточной таблице (MoviesActors) через представление (эта таблица генерируется автоматически в результате отношения «многие ко многим» между Actors и Movies) , Я хочу получить доступ к этой таблице, чтобы я мог назначить правильные первичные ключи для определения таких вещей, как "Сколько фильмов у конкретного актера?" и «Сколько актеров сыграло роль в определенном фильме?».

Это мои модели:

public class Actors
{
    public Actors()
    {
        this.mvz = new HashSet<Movies>();
    }

    public int Id { get; set; }
    public string actor_name { get; set; }
    public string country { get; set; }

    public virtual ICollection<Movies> mvz { get; set; }
}

public class Movies
{
    public Movies()
    {
        this.actz = new HashSet<Actors>();
    }

    public int Id { get; set; }
    public string Movie_title { get; set; }
    public string genre { get; set; }

    public virtual ICollection<Actors> actz { get; set; }
}

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

Теперь из представления я могу получить доступ к модели актеров и модели фильмов, но когда дело доходит до промежуточной таблицы (MoviesActors), я не могу получить доступ к ее модели, потому что она не существует, что означает, что я не могу ссылаться MoviesActors в представлении и не может вводить данные через форму.

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

Кстати, это контроллер:

    public ActionResult DataEntry()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Add(??? mva)
    {
        _context.act.Add(mva.act);
        _context.mvz.Add(mva.mvz);
        _context.SaveChanges();
        return RedirectToAction("Index","Actors");
    }

А это вид:

  @model Many_To_Many_Relationship_Latest.?.?
  @{
      ViewBag.Title = "DataEntry";
      Layout = "~/Views/Shared/_Layout.cshtml";
  }

Вверху я должен иметь доступ к таблице MoviesActors через Model или ViewModel (отметьте два места с вопросительными знаками), но я не могу этого сделать.

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

Большое спасибо заранее.

Это мой новый вид бритвы

    @model Many_To_Many_Relationship_Latest.ViewModel.MoviesActorsViewModel

    <script src="https://code.jquery.com/jquery-3.3.1.min.js"
    integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
    crossorigin="anonymous"></script>



         @{
         ViewBag.Title = "DataEntry";
         Layout = "~/Views/Shared/_Layout.cshtml";
         }

         <h5>Enter Data in Movies_Actors Table</h5>

         @using (Html.BeginForm("Add","MoviesActors"))
         {
       <div class="form-group">
       @Html.LabelFor(a=> a.mvz.Movie_title)
    @Html.TextBoxFor(a=> a.mvz.Movie_title, new { @class="form-control"})
</div>
<div class="form-group">
    @Html.LabelFor(a => a.mvz.genre)
    @Html.TextBoxFor(a => a.mvz.genre, new { @class = "form-control" })
</div>



foreach (var item in Model.act)
{
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <div class="checkbox control-group">
                <label>
                    <!-- SEE id property here, I've made it dynamic -->
                    <input type="checkbox" id="cb_@item.Id" value="@item.Id" class="checkBoxClass" />
                    <label>@item.actor_name</label>
                </label>
            </div>
        </div>
    </div>
}

<div>
    <input type="hidden" name="Ids" id="Ids" />
</div>


<button type="submit" class="btn btn-primary">Save</button>
    }




         <div>
@Html.ActionLink("Back to List", "Index")
        </div>

     <script>
$(function () {

    var ids = [];

    $(".checkBoxClass").change(function () {
        if (this.checked) {
            ids.push(this.value);
        }
        else {
            var index = ids.indexOf(this.value);
            ids.splice(index, 1);
        }
        $('#ids').val(ids);
    });


     });
     </script>

Ответы [ 2 ]

0 голосов
/ 01 сентября 2018

Промежуточная таблица скрыта платформой Entity, но не беспокойтесь, у mvc есть потрясающая функция, которая ViewModel позволяет вам выполнять свою работу, что означает, что вы можете создать представление для промежуточной таблицы, например MoviesActors

Так что,

1) Вы должны создать одну модель представления для промежуточной таблицы, например

public class MoviesActorsViewModel
{
    public MoviesActorsViewModel()
    {
        mvz = new Movies();
        act = new Actors();
    }

    public Movies mvz { get; set; }
    public Actors act { get; set; }
}

2) Добавить вид для вышеупомянутой модели типа

public ActionResult GetView()
{
    MoviesActorsViewModel mcvm = new MoviesActorsViewModel();

    return View(mcvm);
}

3) Тогда ваш взгляд на описанный выше метод действия похож на

.

Приведенная ниже бритва предназначена только для вашего понимания. Ваша фактическая бритва может отличаться от этой.

@model WebApplication2.Controllers.MoviesActorsViewModel

@{
    ViewBag.Title = "GetView";
}

<h2>GetView</h2>

@using (Html.BeginForm("Create", "Default", FormMethod.Post)) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>MoviesActorsViewModel</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        //mvz fields below

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                @Html.TextBoxFor(model => model.mvz.movie_title, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                @Html.TextBoxFor(model => model.mvz.genre, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        //act fields below

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                @Html.TextBoxFor(model => model.act.actor_name, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                @Html.TextBoxFor(model => model.act.country_of_birth, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

4) После того, как вы отправите форму, ваш метод записи добавит ваши mvz и act как

[HttpPost]
public ActionResult Create(MoviesActorsViewModel mcvm)
{
    _context.mvz.Add(mcvm.mvz);
    _context.actrs.Add(mcvm.act);
    return RedirectToAction("GetView", "Default");
}

Примечание : приведенный выше фрагмент кода предназначен для одного фильма и одного актера. Поэтому, если вы хотите добавить нескольких актеров в один фильм, измените свойство act в MoviesActorsViewModel на List Например, public List<Actors> act { get; set; }, добавьте несколько текстовых полей в поле зрения и после отправки формы в метод действия Create добавьте несколько таких акторов, как _context.actrs.AddRange(mcvm.act);

Edit:

Я тоже должен зарегистрировать нового актера. Но я хочу выбрать актеров из таблицы актеров и назначить их для новых регистрируемых фильмов.

Если при добавлении нового фильма вам нужно назначить нескольких актеров для фильма,

1) Вы просматриваете модель

public class MoviesActorsViewModel
{
    public MoviesActorsViewModel()
    {
        mvz = new Movies();
        act = new List<Actors>();
    }

    public Movies mvz { get; set; }
    public List<Actors> act { get; set; }
    public string[] ids { get; set; }
}

2) Заполните ваши актеры из базы данных, чтобы просмотреть список действий модели из вашего метода действия get view

public ActionResult GetView()
{
    MoviesActorsViewModel mcvm = new MoviesActorsViewModel();
    mcvm.act = _context.actrs.ToList();
    return View(mcvm);
}

3) В режиме просмотра бритвы необходимо ввести один фильм и выбрать для него несколько актеров, затем просто установить флажок для каждого из акторов и добавить соответствующие значения id в массив, а затем передать этот массив с отправкой формы.

@model WebApplicationMVC1.Controllers.MoviesActorsViewModel

<script src="https://code.jquery.com/jquery-3.3.1.min.js"
        integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
        crossorigin="anonymous"></script>

@{
    ViewBag.Title = "GetView";
}

<h2>GetView</h2>

@using (Html.BeginForm("Create", "Default1", FormMethod.Post))
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>MoviesActorsViewModel</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        //mvz fields below

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                @Html.TextBoxFor(model => model.mvz.movie_title, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                @Html.TextBoxFor(model => model.mvz.genre, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        //act fields below from list of actors

        @foreach (var item in Model.act)
        {
            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <div class="checkbox control-group">
                        <label>
                            <!-- SEE id property here, I've made it dynamic -->
                            <input type="checkbox" id="cb_@item.Id" value="@item.Id" class="checkBoxClass" />
                            <label>@item.actor_name</label>
                        </label>
                    </div>
                </div>
            </div>
        }

        <div>
            <input type="hidden" name="ids" id="ids" />
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

<script>
    $(function () {

        var ids = [];

        $(".checkBoxClass").change(function () {      
            if (this.checked) {                
                ids.push(this.value);
            }
            else {
                var index = ids.indexOf(this.value);
                ids.splice(index, 1);
            }
            $('#ids').val(ids);
        });


    });
</script>

4) После того, как вы отправите форму для действия ниже, вы можете просмотреть каждого из id актера и сохранить его в базе данных с фильмом

[HttpPost]
public ActionResult Create(MoviesActorsViewModel mcvm)
{
    _context.mvz.Add(mcvm.mvz);

    foreach (var id in mcvm.ids)
    {
        int id1 = Convert.ToInt32(id);
        Actors act = _context.actrs.Find(x => x.Id == id1);
        _context.actrs.Add(act);
    }


    return RedirectToAction("GetView", "Default");
}
0 голосов
/ 01 сентября 2018

@ Prince_Walizada, как вы сказали, у вас есть третья таблица, которая называется Junction Table, и при использовании EF нет необходимости обращаться к этой таблице. потому что вы можете напрямую добавить любой номер другого объекта в текущую запись.

Например (это псевдокод):

 var Movie = MyContext.Movies.Where(P=>Title.Contains("Star war")).FirstOrDefault();
 Movie.Actors.Add(new Actor() { Name = "Mike" , ...}
 Movie.Actors.Add(new Actor() { Name = "Joe" , ...}
 Movie.Actors.Add(new Actor() { Name = "Daniel" , ...}

и вы можете сделать это также в обратном порядке:

 var Actor = MyContext.Movies.Where(P=>Name.Contains("Mike")).FirstOrDefault();
 Actor.Movies.Add(new Movie() { Title = "World of War" , ...}
 Actor.Movies.Add(new Movie() { Title = "hobbits" , ...}
 Actor.Movies.Add(new Movie() { Title = "toy story" , ...}

Как видите, вам не нужно знать об этом третьем столе.

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