我需要在联接表中设置主键吗? MVC多对多关系

时间:2018-11-12 21:32:52

标签: asp.net asp.net-mvc

有疑问的是:联接表中是否需要主键?

我有工作表:

 public partial class Job
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Job()
    {
        this.Room = new HashSet<Room>();
    }

    public int JobID { get; set; }
    public string Title { get; set; }
    public Nullable<int> DepartmentID { get; set; }

    public virtual Department Department { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Room> Room { get; set; }
}

和用户表:

public partial class AspNetUsers
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public AspNetUsers()
    {
        this.Department = new HashSet<Department>();
    }

    public string Id { get; set; }
    public string Email { get; set; }
    public bool EmailConfirmed { get; set; }
    public string PasswordHash { get; set; }
    public string SecurityStamp { get; set; }
    public string PhoneNumber { get; set; }
    public bool PhoneNumberConfirmed { get; set; }
    public bool TwoFactorEnabled { get; set; }
    public Nullable<System.DateTime> LockoutEndDateUtc { get; set; }
    public bool LockoutEnabled { get; set; }
    public int AccessFailedCount { get; set; }
    public string UserName { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Nullable<int> PhoneNo { get; set; }
    public Nullable<System.DateTime> HireDate { get; set; }
    public Nullable<System.DateTime> BirthDate { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Department> Department { get; set; }
}

每个用户可以在几个部门中,每个部门可以有很多用户。

在我的控制器中:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Praca.Models;
using Praca.ViewModels;

namespace Praca.Controllers
{
public class EmployeeController : Controller
{
    private Entities1 db = new Entities1();

    // GET: Employee
    public ActionResult Index(string id)
    {
        var viewModel = new AspNetUserDepartmentVM();
        viewModel.AspNetUsers = db.AspNetUsers
            .Include(i => i.Department)
            .OrderBy(i => i.LastName);

        if (id != null)
        {
            ViewBag.EmployeeID = id;
            viewModel.Departments = viewModel.AspNetUsers.Where(
                i => i.Id == id).Single().Department;
        }

        return View(viewModel);
    }

    // GET: Employee/Details/5
    public ActionResult Details(string id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        AspNetUsers aspNetUsers = db.AspNetUsers.Find(id);
        if (aspNetUsers == null)
        {
            return HttpNotFound();
        }
        return View(aspNetUsers);
    }

    // GET: Employee/Create
    public ActionResult Create()
    {
        return View();
    }

    // POST: Employee/Create
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see https://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "Id,Email,EmailConfirmed,PasswordHash,SecurityStamp,PhoneNumber,PhoneNumberConfirmed,TwoFactorEnabled,LockoutEndDateUtc,LockoutEnabled,AccessFailedCount,UserName,FirstName,LastName,PhoneNo,HireDate,BirthDate")] AspNetUsers aspNetUsers)
    {
        if (ModelState.IsValid)
        {
            db.AspNetUsers.Add(aspNetUsers);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(aspNetUsers);
    }

    // GET: Employee/Edit/5
    public ActionResult Edit(string id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        AspNetUsers aspNetUsers = db.AspNetUsers
            .Include(i => i.Department)
            .Where(i => i.Id == id)
            .Single();
        PopulateAssignedCourseData(aspNetUsers);
        if (aspNetUsers == null)
        {
            return HttpNotFound();
        }
        return View(aspNetUsers);
    }

    private void PopulateAssignedCourseData(AspNetUsers aspNetUsers)
    {
        var allCourses = db.Department;
        var instructorCourses = new HashSet<int>(aspNetUsers.Department.Select(c => c.DepartmentID));
        var viewModel = new List<AssignedDepartment>();
        foreach (var course in allCourses)
        {
            viewModel.Add(new AssignedDepartment
            {
                DepartmentID = course.DepartmentID,
                DepartmentName = course.DepartmentName,
                Assigned = instructorCourses.Contains(course.DepartmentID)
            });
        }
        ViewBag.Courses = viewModel;
    }

    // POST: Employee/Edit/5
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see https://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(string id, string[] selectedCourses)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        var instructorToUpdate = db.AspNetUsers
           .Include(i => i.Department)
           .Where(i => i.Id == id)
           .Single();

        if (TryUpdateModel(instructorToUpdate, "",
           new string[] { "LastName"}))
        {
            try
            {

                UpdateInstructorCourses(selectedCourses, instructorToUpdate);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            catch (RetryLimitExceededException /* dex */)
            {
                //Log the error (uncomment dex variable name and add a line here to write a log.
                ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
            }
        }
        PopulateAssignedCourseData(instructorToUpdate);
        return View(instructorToUpdate);
    }
    private void UpdateInstructorCourses(string[] selectedCourses, AspNetUsers instructorToUpdate)
    {
        if (selectedCourses == null)
        {
            instructorToUpdate.Department = new List<Department>();
            return;
        }

        var selectedCoursesHS = new HashSet<string>(selectedCourses);
        var instructorCourses = new HashSet<int>
            (instructorToUpdate.Department.Select(c => c.DepartmentID));
        foreach (var course in db.Department)
        {
            if (selectedCoursesHS.Contains(course.DepartmentID.ToString()))
            {
                if (!instructorCourses.Contains(course.DepartmentID))
                {
                    instructorToUpdate.Department.Add(course);
                }
            }
            else
            {
                if (instructorCourses.Contains(course.DepartmentID))
                {
                    instructorToUpdate.Department.Remove(course);
                }
            }
        }
    }




    // GET: Employee/Delete/5
    public ActionResult Delete(string id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        AspNetUsers aspNetUsers = db.AspNetUsers.Find(id);
        if (aspNetUsers == null)
        {
            return HttpNotFound();
        }
        return View(aspNetUsers);
    }

    // POST: Employee/Delete/5
    [HttpPost, ActionName("Delete")]
    [ValidateAntiForgeryToken]
    public ActionResult DeleteConfirmed(string id)
    {
        AspNetUsers aspNetUsers = db.AspNetUsers.Find(id);
        db.AspNetUsers.Remove(aspNetUsers);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }
        base.Dispose(disposing);
        }
    }
}`

不幸的是,我遇到错误:无法更新EntitySet'AspNetUsersDepartment',因为它具有DefiningQuery并且该元素中不存在任何元素来支持当前操作。

如何解决此问题? 当我在该表上设置主键时,没有多对多的关系,而是两个一对多的关系。

1 个答案:

答案 0 :(得分:0)

好。我已经为自己搞定了。.

如果有人也有这种问题:

您必须设置主键,但不能在表中将其设置为单独的值。 就我而言

CONSTRAINT [PK_dbo.AspNetUserDepartment] PRIMARY KEY CLUSTERED ([EmployeeId] ASC, [DepartmentId] ASC),

工作完美。