构建创建 mvc5(代码优先)的模型,其关系为一对多(N-arry?)的固定数量的许多元素



这是我在这里的第一个问题,如果我做错了什么,很抱歉。我在这里没有找到答案。

我需要使用以下元数据构建我的数据库:

public class Room
{
    [Key]
    public int RoomID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Student> Students {get;set;}
}
public class Student 
{
    [Key]
    public int StudentID { get; set; }
    public string Name { get; set; }
}

每个房间最多可容纳 20 名学生。 它可以是 0 名学生、5 名学生或 20 名学生,但不能更多。

我该怎么做?

注意: 我知道我可以更改行:

public virtual ICollection<Student> Students {get;set;}

像这样:

public virtual  Student Student-01 {get;set;}
public virtual  Student Student-02 {get;set;}
....
public virtual  Student Student-20 {get;set;}

但我正在寻找更优雅的解决方案。

我也知道我可以在房间创建/编辑操作的控制器中控制学生人数

但我只想更改DB(模型),除非没有其他解决方案?

谢谢

这似乎是可以通过EF的验证功能实现的:

  • 您可以尝试的一件事是在其中一个班级上实施IValidatableObject,以验证学生人数是否低于最大限制。过去,我会从关系的"许多"方面这样做,但你的Student模型似乎没有参考它的Room
  • 另一种选择是覆盖DbContext.ValidateEntity

任一情况下,验证都将在调用DbContext.SaveChangesDbContext.GetValidationErrors时发生。

有关实体框架验证的详细信息,可以在 MSDN 上查看此文章。

感谢@jjj和这里的每个人,这就是我解决这个问题的方式(基于 IValidatableObject 实现):

模型:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
namespace College.Models
{
    public class Student : IValidatableObject
    {
        [Key]
        public int StudentID { get; set; }
        public string Name { get; set; }
        public virtual Room Room { get; set; }
        //validation:
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (Room.Students.Count() > 20)
                yield return new ValidationResult("Too many students in class", new[] { "RoomId" });
        }

    }
public class Room
{
    public Room()
    {
        Students = new List<Student>();
    }
    [Key]
    public int RoomID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Student> Students {get;set;}
}
}

控制器:

// POST: Rooms/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for 
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Room room)
{
    try
    {
        if (ModelState.IsValid)
        {
            db.Entry(room).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(post);
    }
    catch (DbEntityValidationException ex)
    {
        var error = ex.EntityValidationErrors.First().ValidationErrors.First();
        this.ModelState.AddModelError(error.PropertyName, error.ErrorMessage);
        return View(room);
    }
}

视图:

@Html.ValidationMessageFor(model => model.RoomId, "", new { @class = "text-danger" })

最新更新