C# 在db中插入列表作为外键值
我有那个数据库 学生可以有多个科目。所以我就这样存储它们: 学号:1,姓名:数学;学号:1,姓名:地理 等等 我在Viewbag中有主题:C# 在db中插入列表作为外键值,c#,sql,sql-server,asp.net-mvc,entity-framework,C#,Sql,Sql Server,Asp.net Mvc,Entity Framework,我有那个数据库 学生可以有多个科目。所以我就这样存储它们: 学号:1,姓名:数学;学号:1,姓名:地理 等等 我在Viewbag中有主题: ViewBag.Subjects = new SelectList(new[] { "Math", "Phisic", "Chemic", "English" } .Select(x => new { value = x, text = x }), "Value", "Text");
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");
}
[HttpPost]
[ValidateAntiForgeryToken]
公共异步任务注册表([Bind(Include=“Id、姓名、姓氏、出生日期、性别、科目”)]Students-student)
{
如果(!ModelState.IsValid)
{
主题列表();
返回视图();
}
学生=新学生();
_student.Name=student.Name;
_学生。姓氏=学生。姓氏;
_student.Gender=student.Gender;
_student.BirthDate=student.BirthDate;
主题_Subject=新主题();
如果(!student.Subject.Any())
{
foreach(student.Subject中的变量项)
{
_db.Subjects.Add(item);//这里它抛出了一个异常错误重载
}
}
_db.student.Add(_student);
等待_db.SaveChangesAsync();
返回操作(“索引”);
}
我的学生在这里上课:
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; }
}
公共班级学生
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串姓氏{get;set;}
公共字符串{get;set;}
公共日期时间?生日{get;set;}
公共列表主题{get;set;}
}
我的问题是如何在我的主题表中添加主题值您的类应该如下所示:
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();
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
}
}
公共类科目
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟列表学生{get;set;}
}
公立班学生
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟列表主题{get;set;}
}
然后,您可以向学生添加科目,如下所示:
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();
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
}
}
var主题=新主题
{
Name=“物理学”
};
_db.subject.Add(subject);
学生=新生
{
Name=“venerik”,
主题=新列表{subject}
};
_db.Students.Add(学生);
_db.SaveChanges();
在此设置中,EF将为学生和科目创建一个表,并创建一个名为SubjectStudent的交叉表(正如@Clockwork Muse已经建议的那样)。我将不再讨论改进数据模型以更好地反映现实的可能性(因为评论中已经对此进行了一些重要讨论),因此,考虑到实际数据模型的约束条件,下面是我的答案: EF(以及普通的旧Linq到SQL)的设计方式处理外部事务 在ORM级别创建关键关系,这样您就不必这样做 EF生成的ORM实体(其中涉及外键)创建一对多关系作为列表对象,这些关系称为
导航属性
。让我们了解一下这是如何工作的
因此,您不需要将单个主题
明确添加到主题
表中
由于Student
和Subject
表具有外键关系,因此在Student
对象上具有列表就足够了,EF将为您处理插入操作
关于您收到的异常的注释:
您当前的代码包含学生类科目的字符串列表:
public List<string> Subject { get; set; }
然后您仍然只需执行\u db.Students.Add(\u student)代码>它会起作用。问题是……我认为您正在尝试实现类似的目标:这也会有所帮助@venerik我个人更新了我的问题,我认为你的数据模型是错误的;你可以有没有学生的科目,对吗?两个学生共用一个科目怎么样?实际上,您可能希望从subjects表中删除studentId
,并创建一个新的“交叉引用”表,其中只包含studentId
和subjectId
。