简体   繁体   English

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

[英]insert list in db as foreign key value

I have that db 我有那个分贝

在此处输入图片说明

And Student can have multiple Subjects. 学生可以有多个科目。 So I'm storing them like that: 所以我像这样存储它们:

StudentId: 1, Name: Math; StudentId:1,名称:Math; StudentId: 1, Name: Geography StudentId:1,名称:Geography

etc.. 等等..

I have subjects in Viewbag: 我在Viewbag中有主题:

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

And user can select multiple items at once. 用户可以一次选择多个项目。 When I'll register new student It must insert that student's subjects as well. 当我注册新学生时,还必须插入该学生的科目。 For them I'm that: 对于他们来说,我就是:

        [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");
        }

And my Students class is here: 我的学生班在这里:

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; }
}

My question is how can I add that subject values in my Subject table 我的问题是如何在我的“主题”表中添加该主题值

Your classes should look like this: 您的课程应如下所示:

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;}
}

You can then add subjects to students like this: 然后,您可以像这样向学生添加科目:

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();

In this set up EF will create a table for both Student and Subject and an intersection table called SubjectStudent (as @Clockwork-Muse already suggested). 在此设置中,EF将为Student和Subject创建一个表,以及一个称为SubjectStudent的交叉表(如已经建议的@ Clockwork-Muse)。

I am going to refrain on the potential for improving your data model to better reflect reality for now (as there is already some great discussion on this in the comments) , so given the constraints of what your actual data model looks like, here's my answer: 我将暂时避免改善数据模型以更好地反映现实的潜力(因为评论中对此已经进行了很多讨论) ,因此鉴于实际数据模型的局限性,这是我的答案:

The way EF (and plain old Linq-To-SQL) are designed handles foreign key relationships at the ORM level, so that you do not have to. EF(和普通的Linq-To-SQL)的设计方式是在ORM级别处理外键关系的,因此您不必这样做。

The ORM entities generated by EF where foreign keys are involved create one-to-many relationships as List objects, and these are called navigation properties . EF生成的涉及外键的ORM实体创建了一对多关系作为List对象,这些关系称为navigation properties This article sheds some light on how this works. 本文阐明了其工作原理。

Thus, you do not need to add the individual subjects to the Subject table explicitly; 因此,你不需要单独添加subjectsSubject表明确;

Since the Student and Subject tables have a foreign key relationship, having the List<Subject> on the Student objects is sufficient and EF will handle the inserts for you. 由于StudentSubject表具有外键关系,因此在Student对象上具有List<Subject>就足够了,EF会为您处理插入。


A note on the exception you're getting: 关于您得到的异常的注释:

Your current code has a list of strings for subjects on the student class: 您当前的代码中有一个针对学生班级学科的字符串列表:

public List<string> Subject { get; set; }

Then you are trying to insert the strings into the _db.Subjects ( DbSet<Subject> ) instance, which is why you're getting the exception. 然后,您尝试将字符串插入_db.Subjects( DbSet<Subject> )实例中,这就是为什么您要获取异常的原因。


Solution: 解:

  • Make a Subjects class that mimics your EF Subject table (since it appears you're creating custom classes to mimic the ORM entities, which is a practice I personally like since it decouples the ORM from the final consumer of the data such as your front end) 制作一个模仿您的EF Subject表的Subjects(因为看起来您正在创建模仿ORM实体的自定义类,所以我个人喜欢这种做法,因为它使ORM与数据的最终使用者(如前端)分离)

  • Change the Students class to have List<Subjects> instead of List<string> for the Subjects property. Students类更改为具有Subject属性的List<Subjects>而不是List<string>

Then your code to insert the records would look something roughly like this: 然后,用于插入记录的代码将大致如下所示:

Student _student = new Student();
_student.Name = student.Name;
_student.Surname = student.Surname;
_student.Gender = student.Gender;          
_student.BirthDate = student.BirthDate;

// I removed the ! here because it seems pointless to check that you have no elements, and then try to add them....
if (student.Subject.Any())
{
    foreach (var item in student.Subjects)
    {
         // this is the ORM subject now, the names seem ambiguous 
         // but the important thing is you have are filling the List<Subject>
         // of the Student ORM entity with Subject ORM entities,
         // which will cause the ORM to handle the foreign key relationship
         // and insert items into the Subjects table

         _student.Subjects.Add(new Subject() { 
             Name = item.Name
         });

         // Note: the ORM will handle the StudentId field, and I assume
         // the Id field is an SQL Identity and will be auto-generated;
         // If not then, aside from, 'why not?', you'd populate it manually
    }
}

Then you still just do _db.Students.Add(_student); 然后您仍然只需执行_db.Students.Add(_student); and it will work. 它会工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM