在db中插入列表作为外键值

时间:2015-11-11 13:56:19

标签: c# sql sql-server asp.net-mvc entity-framework

我有那个db

enter image description here

学生可以有多个科目。所以我就像那样存储它们:

  

StudentId:1,姓名:数学; StudentId:1,姓名:地理

等。

我在Viewbag中有主题:

ViewBag.Subjects = new SelectList(new[] { "Math", "Phisic", "Chemic", "English" }
                .Select(x => new { value = x, text = x }),
                "Value", "Text");

用户可以一次选择多个项目。 当我注册新学生时,必须插入该学生的科目。对他们来说,我就是这样:

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Register([Bind(Include = "Id,Name,Surname,BirthDate,Gender,Subject")] Students student)
        {
            if (!ModelState.IsValid)
            {
                SubjectsList();
                return View();
            }
            Student _student = new Student();
            _student.Name = student.Name;
            _student.Surname = student.Surname;
            _student.Gender = student.Gender;
            _student.BirthDate = student.BirthDate;

            Subject _subject = new Subject();
            if (!student.Subject.Any())
            {
                foreach (var item in student.Subject)
                {
                   _db.Subjects.Add(item);//Here it throws an exception Wrong overload
                }
            }


            _db.Students.Add(_student);
            await _db.SaveChangesAsync();

            return RedirectToAction("Index");
        }

我的学生课程就在这里:

public class Students
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Gender { get; set; }
    public DateTime? BirthDate { get; set; }
    public List<string> Subject { get; set; }
}

我的问题是如何在主题表格中添加该主题值

2 个答案:

答案 0 :(得分:1)

您的课程应如下所示:

public class Subject
{
    public int Id {get;set;}
    public string Name {get;set;}
    public virtual List<Student> Students {get;set;}
}

public class Student
{
    public int Id {get;set;}
    public string Name {get;set;}
    public virtual List<Subject> Subjects {get;set;}
}

然后,您可以向学生添加这样的主题:

var subject = new Subject 
{ 
    Name = "Physics" 
};
_db.Subjects.Add(subject);

var student = new Student 
{ 
    Name = "venerik", 
    Subjects = new List<Subject> { subject }
};
_db.Students.Add(student);
_db.SaveChanges();

在此设置中,EF将为学生和主题创建一个表,并创建一个名为SubjectStudent的交集表(已建议使用@ Clockwork-Muse)。

答案 1 :(得分:1)

我将避免改进您的数据模型的潜力,以便更好地反映现实(因为在评论中已经对此进行了一些很好的讨论),所以考虑到了什么的限制您的实际数据模型如下所示,这是我的答案:

  

EF(和普通的旧Linq-To-SQL)设计的方式处理异类   ORM级别的关键关系,因此您不必这样做。

     

由EF生成的ORM实体(其中涉及外键)创建一对多关系作为List对象,这些实体称为AnimatableThis article阐明了这是如何运作的。

因此,您无需明确地将find DIR_A -maxdepth 1 -type f -mmin +10 -exec mv "{}" DIR_B/ \ 个人navigation properties添加到subjects表中;

由于SubjectStudent表具有外键关系,因此在Subject对象上使用List<Subject>就足够了,EF将为您处理插入。< / p>

关于您获得的例外的说明:

您当前的代码中包含学生班级科目的字符串列表:

Student

然后您尝试将字符串插入_db.Subjects(public List<string> Subject { get; set; } )实例,这就是您获得异常的原因。

<强>解决方案:

  • 创建一个模仿EF主题表DbSet<Subject>类(因为看起来您正在创建自定义类来模仿ORM实体,这是我个人喜欢的一种做法,因为它将ORM与数据的最终消费者(例如您的前端)分离开来

  • 将“Subjects”课程更改为“{1}}而不是Students”。

然后,您插入记录的代码看起来大致如下:

List<Subjects>

然后你仍然只做List<string>它会起作用。