@Saharman

Как сохранить данные со связью многие ко многим?

Не получается сохранить данные при связи многие ко многим. Есть три таблицы: Person, Project и ProjectPerson(промежуточная таблица).
Вот реализация модели Project:
public partial class Project
    {
        public Project()
        {
            ProjectPerson = new HashSet<ProjectPerson>();
        }
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public DateTime IncomeDate { get; set; }
        public int? LeaderId { get; set; }
        public Person Leader { get; set; }
        public ICollection<ProjectPerson> ProjectPerson { get; set; }
    }
}

Реализация модели Person:
public partial class Person
    {
        public Person()
        {
            Project = new HashSet<Project>();
            ProjectPerson = new HashSet<ProjectPerson>();
        }

        public int Id { get; set; }
        public string FullName { get; set; }
        public string PhoneNumber { get; set; }
        public string Email { get; set; }
        public string Vk { get; set; }
        public string Instagram { get; set; }
        public string Facebook { get; set; }
        public string Twitter { get; set; }
        public ICollection<Project> Project { get; set; }
        public ICollection<ProjectPerson> ProjectPerson { get; set; }
    }
}

Реализация модели ProjectPerson:
public partial class ProjectPerson
    {
        public int ProjectId { get; set; }
        public int PersonId { get; set; }
        public Person Person { get; set; }
        public Project Project { get; set; }
    }

Дополнительно DBcontext:
modelBuilder.Entity<Person>(entity =>
            {
                entity.ToTable("person");

                entity.Property(e => e.Id).HasColumnName("ID");

                entity.Property(e => e.Email)
                    .HasColumnName("email")
                    .HasMaxLength(200);

                entity.Property(e => e.Facebook)
                    .HasColumnName("facebook")
                    .HasMaxLength(200);

                entity.Property(e => e.FullName)
                    .IsRequired()
                    .HasColumnName("full_name")
                    .HasMaxLength(200);

                entity.Property(e => e.Instagram)
                    .HasColumnName("instagram")
                    .HasMaxLength(200);

                entity.Property(e => e.PhoneNumber)
                    .HasColumnName("phone_number")
                    .HasMaxLength(50);

                entity.Property(e => e.Twitter)
                    .HasColumnName("twitter")
                    .HasMaxLength(200);

                entity.Property(e => e.Vk)
                    .HasColumnName("vk")
                    .HasMaxLength(200);
            });
 modelBuilder.Entity<Project>(entity =>
            {
                entity.ToTable("project");

                entity.Property(e => e.Id).HasColumnName("id");

                entity.Property(e => e.Description)
                    .IsRequired()
                    .HasColumnName("description")
                    .HasColumnType("text");

                entity.Property(e => e.IncomeDate)
                    .HasColumnName("incomeDate")
                    .HasColumnType("date");

                entity.Property(e => e.LeaderId).HasColumnName("leader_id");

                entity.Property(e => e.Name)
                    .IsRequired()
                    .HasColumnName("name")
                    .HasColumnType("nchar(50)");

                entity.HasOne(d => d.Leader)
                    .WithMany(p => p.Project)
                    .HasForeignKey(d => d.LeaderId)
                    .HasConstraintName("FK_project_person");
            });
modelBuilder.Entity<ProjectPerson>(entity =>
            {
                entity.HasKey(e => new { e.ProjectId, e.PersonId });

                entity.ToTable("project_person");

                entity.Property(e => e.ProjectId).HasColumnName("project_id");

                entity.Property(e => e.PersonId).HasColumnName("person_id");

                entity.HasOne(d => d.Person)
                    .WithMany(p => p.ProjectPerson)
                    .HasForeignKey(d => d.PersonId)
                    .OnDelete(DeleteBehavior.ClientSetNull)
                    .HasConstraintName("FK_project_person_person");

                entity.HasOne(d => d.Project)
                    .WithMany(p => p.ProjectPerson)
                    .HasForeignKey(d => d.ProjectId)
                    .OnDelete(DeleteBehavior.ClientSetNull)
                    .HasConstraintName("FK_project_person_project");
            });

Вот контроллер:
[HttpGet]
        public IActionResult Create()
        {
            ViewBag.Persons = new SelectList(_context.Person.ToList(), "Id", "FullName");
            return View();
        }
[HttpPost]
        public IActionResult Create(Project project)
        {
            _context.Project.Add(project);
            _context.SaveChanges();
            return RedirectToAction("Index");
        }

И вот вьюшка:
<form class="form" asp-action="Create" asp-controller="Project" method="post" enctype="multipart/form-data">
                    <div class="form-group row">
                        <label class="col-md-12" asp-for="Name">Название проекта</label>
                        <div class="col-md-12">
                            <input type="text" class="form-control"  asp-for="Name">
                        </div>
                    </div>
                    <div class="form-group row">
                        <label class="col-md-12" asp-for="Description">Описание</label>
                        <div class="col-md-12">
                            <textarea class="form-control" rows="4" asp-for="Description"></textarea>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label class="col-sm-12" asp-for="LeaderId">Лидер</label>
                        <div class="col-sm-12">
                            <select class="custom-select col-12" id="inlineFormCustomSelect" asp-for="LeaderId" asp-items="ViewBag.Persons"><option selected="selected" disabled="disabled">Выберите руководителя</option></select>
                        </div>
                    </div>

                    <div class="form-group row">
                        <label class="col-sm-12" asp-for="ProjectPerson">Команда</label>
                        <div class="col-sm-12">
                            <select class="custom-select col-12" id="inlineFormCustomSelect" asp-for="ProjectPerson" asp-items="ViewBag.Persons" multiple><option selected="selected" disabled="disabled">Выберите руководителя</option></select>
                        </div>
                    </div>
                   <input type="submit" value="Добавить" class="btn btn-common">
                </form>


Хочу заметить, что модели и контекс прописывал не я, они создаются сами из бд MSQL
  • Вопрос задан
  • 738 просмотров
Решения вопроса 1
DarkRaven
@DarkRaven
разработка программного обеспечения
В вашем случае - вам нужно просто добавить ProjectPerson с соответствующими значениями в project или person. И сохранить.
А вообще, ее нужно удалить и настроить модель примерно так:
modelBuilder.Entity<Project>()
                .HasMany<Person>(s => s.Persons)
                .WithMany(c => c.Projects)
                .Map(cs =>
                        {
                            cs.MapLeftKey("project_id");
                            cs.MapRightKey("person_id");
                            cs.ToTable("project_person");
                        });


Дополнительно:
Важно: Все примеры кода - только для EF6, EF Core не может работать без промежуточной сущности.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@kttotto
пофиг на чем писать
EF самостоятельно создает промежуточные таблицы при отношении многие ко многим. Вам достаточно указать эту связь между таблицами Project и Person. Руками делать их нет необходимости.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы