SQL Server 在ASP.NET核心MVC和实体框架中配置多对多关系

7nbnzgx9  于 2023-02-11  发布在  .NET
关注(0)|答案(2)|浏览(134)

我正尝试在两个表EmployeeProject之间配置多对多关系。
一个Employee可以参与多个项目,一个项目可以有多个Employees参与,所以我创建了两个模型类EmployeeProject,并添加了表Employee_Project
这是我的三个模型类:

namespace WebApp2.Models
{
    public class Employee
    {
        [Key]
        public int Emp_Id { get; set; }
        public string Emp_Name { get; set; }
        public string Emp_Email { get; set; }
        public string Emp_Mobile { get; set; }

        public virtual ICollection<Employee_Project> Employee_Projects { get; set; }
    }

    public class Project
    {
        [Key]
        public int Proj_Id { get; set; }
        public string Proj_Name { get; set; }
        public string Project_Details { get; set; }
        public virtual ICollection<Employee_Project> Employee_Projects { get; set; }
    }

    public class Employee_Project
    {
        [Key]
        [Column(Order =1)]
        public int Emp_Id { get; set; }
        [Key]
        [Column(Order = 2)]
        public int Proj_Id { get; set; }

        public virtual Employee Employee { get; set; }
        public virtual Project Project { get; set; }
    }
}

然后我添加了这个DbContext类:

namespace WebApp2.Data
{
    public class MyDbContext:DbContext
    {
        public MyDbContext(DbContextOptions<MyDbContext> option):base(option)
        {
        }

        public DbSet<Employee> Employees { get; set; }
        public DbSet<Project> Projects { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Employee_Project>().HasKey(pt => new { pt.Proj_Id, pt.Emp_Id });

            modelBuilder.Entity<Employee_Project>()
                        .HasOne(pt => pt.Employee)
                        .WithMany(pt => pt.Employee_Projects)
                        .HasForeignKey(p => p.Emp_Id);

            modelBuilder.Entity<Employee_Project>()
                        .HasOne(pt => pt.Project)
                        .WithMany(pt => pt.Employee_Projects)
                        .HasForeignKey(p => p.Proj_Id);
        }

        public DbSet<Employee_Project> Employee_Projects { get; set; }
    }
}

之后我创建了三个控制器

public class ProjectController : Controller
    {
        private readonly MyDbContext _context;

        public ProjectController(MyDbContext context)
        {
            _context = context;
        }
        public IActionResult Index()
        {
            return View(_context.projects.ToList());
        }

        public IActionResult Create()
        {
            return View();
        }
        [HttpPost]
        public IActionResult Create(Project project)
        {
            _context.projects.Add(project);
            _context.SaveChanges();
            return RedirectToAction("Index");
        }
    }



public class EmployeeController : Controller
    {
        private readonly MyDbContext _context;

        public EmployeeController(MyDbContext context)
        {
            _context = context;
        }
        public IActionResult Index()
        {
            return View(_context.Employees.ToList());
        }

        public IActionResult Create()
        {
            return View();
        }
        [HttpPost]
        public IActionResult Create(Employee employee)
        {
             _context.Employees.Add(employee);
            _context.SaveChanges(); 
            return RedirectToAction("Index");
        }
    }



public class Emp_ProjController : Controller
    {
        private readonly MyDbContext _DbContext;

        public Emp_ProjController(MyDbContext DbContext)
        {
            _DbContext = DbContext;
        }
        public IActionResult Index()
        {
            return View(_DbContext.Employee_Projects.ToList());
        }

        
        public IActionResult Create()
        {
            ViewBag.emp=_DbContext.Employees.ToList();
            ViewBag.pro=_DbContext.projects.ToList();
            return View();
        }

        [HttpPost]
        public IActionResult Create(int empid, int [] projIds)
        {
            foreach (var item in projIds)
            {
                Employee_Project emp = new Employee_Project();
                emp.Emp_Id = empid;
                emp.Proj_Id = item;
                _DbContext.Employee_Projects.Add(emp);
                _DbContext.SaveChanges();

            }
            return RedirectToAction("Index");
            
            
        }

    }

在foreach控制器之后,我为方法Index和Create创建了视图
员工_项目
//查看索引

@model IEnumerable<WebApp2.Models.Employee_Project>

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Employee.Emp_Name)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Project.Proj_Name)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Employee.Emp_Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Project.Proj_Name)
            </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>
}
    </tbody>
</table>

//view Create

<h2>Create</h2>

<form method="post">
    <div>
        <label>Employee Name</label>
        @Html.DropDownList("empid", new SelectList(ViewBag.emp, "Emp_Id","Emp_Email"),"Select Employee")
    </div>
    <div>
        <label>Select Project</label>
       @* @Html.DropDownList("proid", new SelectList(ViewBag.pro, "Proj_Id","Proj_Name"),"Select Project")*@

        <ul>
            @foreach(var item in ViewBag.pro )
            {
                <li>
                    <input type="checkbox" name="projIds" value="@item.Proj_Id">@item.Proj_Name
                </li>
            }
        </ul>

        <input  type="submit" value="SaveData"/>
        
    </div>
</form>

我在Employee和项目中没有问题,我在创建Emp_Proj元素enter image description here时发现了问题,它总是给我这样的错误:
SQL异常:违反了PRIMARY KEY约束'PK_Employee_Projects'。无法将重复的键插入到对象'dbo.Employee_Projects'中。重复的键值:(1,1).指令已终止
enter image description here
有人能帮我找到问题吗?先谢了。
我试图找到问题所在,我很感激你的帮助。

mpgws1up

mpgws1up1#

错误消息显示了导致此异常的原因:数据库中已经存在此记录,不能插入重复数据,插入数据前只需检查数据库中是否存在此记录,请参考此简单演示。

[HttpPost]
        public IActionResult Create(int empid, int[] projIds)
        {
            foreach (var item in projIds)
            {
                //check if the database already has this record
                var empdb = _DbContext.Employee_Projects.Where(x => x.Emp_Id == empid && x.Proj_Id == item).FirstOrDefault();

                if (empdb==null)
                {
                    Employee_Project emp = new Employee_Project();
                    emp.Emp_Id = empid;
                    emp.Proj_Id = item;
                    _DbContext.Employee_Projects.Add(emp);
                }
                
           
            }
            _DbContext.SaveChanges();
            return RedirectToAction("Index");
        }
5vf7fwbs

5vf7fwbs2#

首先,尝试完全删除“Employee_Project”实体,并查看EF Core是否可以自动创建它。EF Core应该能够自动生成关联表,只要在两个实体上设置了两个导航属性。请注意,两个实体的导航属性应该相互引用。如下所示;
在员工中;

public virtual ICollection<Project> Projects { get; set; }

和项目中;

public virtual ICollection<Employee> Employees { get; set; }

如果这样做不起作用,请像这样修改Employee_Project类;

public class Employee_Project
    {
        [Key]
        [Column(Order =1)]
        public int EmployeeId { get; set; }
        [Key]
        [Column(Order = 2)]
        public int ProjectId { get; set; }

        public virtual Employee Employee { get; set; }
        public virtual Project Project { get; set; }
    }

列的命名可能是问题所在。

相关问题