如何在ASP.NET MVC中使用Entity Framework将记录插入具有外键的表中

Rai*_*Adn 9 c# entity-framework ef-code-first-mapping

我是Entity Framework代码优先的新手。这是我在ASP.NET MVC中的学习,使用代码优先的数据库创建。

我有两节课:

public class Student
{
    public int StudentId { get; set; }
    public string Name { get; set; }
    public int Standard { get; set; }            
    public int SubjectId { get; set; }    

    [ForeignKey("SubjectId")]
    public ICollection<Subject> Subjects { get; set; }
}

public class Subject
{
    [Key]
    public int SubjectId{ get; set; }
    public string SubjectName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试向表中插入一条Student记录Student,该记录具有SubjectId引用该Subject表的外键。

我正在尝试两种可能的方法:

第一种方法

using(var cxt = new SchoolContext())
{
    Subject sub = new Subject() { SubjectId = 202, SubjectName ="Geology" };
    Student stu = new Student() { Name = "Riya", SubjectId = 202 };
    cxt.Subjects.Add(sub);
    cxt.Students.Add(stu);           

    cxt.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

在这里,我创建了一个新Subject实例,该实例具有SubjectId=202。现在,当我创建Student对象并将值202分配给时SubjectId,将发生Insert语句冲突。尽管有一个Subjectwith SubjectId = 202,那么为什么会有插入冲突?当我调试时,我看到Subjects这里的navigation属性为null。我不明白这里的意思。

第二种方法:

using( var cxt=new SchoolContext())
{
    Student stu = new Student() { Name = "Riya" };
    Subject sub = new Subject() { SubjectId = 202, SubjectName = "Geology" };
    stu.Subjects.Add(sub);
    cxt.Students.Add(stu);               

    cxt.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

但是我得到一个空引用异常

对象引用未设置为对象的实例

为什么stu.Subjects这里为null?

所以我的问题是:

  1. 什么是SubjectIdStudent类的意思吗?即它的价值是什么?我们可以显式设置它Subject吗(如果是),它将引用表的主键吗?如果否,是否仅出于EF代码约定的目的而指定?

  2. 同样:导航属性起什么作用?为什么它为null,什么时候不为null?

我对导航属性的基本理解是,它用于使EF确定两个实体之间的关系。

任何人都可以举例说明一下,不胜感激。

mar*_*c_s 7

基本上,您在两种方法中都创建了new Student和new Subject。但是据我了解,您真正想做的是创建一个new Student,并为其分配一个现有的 Subject(带有SubjectId = 202)-对吗?

SubjectId在您的Student班级中,使用in 绝对没有意义-因为您Student和之间的比例为1:n Subject。您需要使用它ICollection<Subject>来处理该学生注册的0:n主题。

为此,请使用以下代码:

using(var ctx = new SchoolContext())
{
    // create the *NEW* Student
    Student stu = new Student() { Name = "Riya" };

    // get existing subject with Id=202
    Subject sub = ctx.Subjects.FirstOrDefault(s => s.SubjectId == 202);

    // Add this existing subject to the new student's "Subjects" collection
    stu.Subjects.Add(sub);

    // Add the new student to the context, and save it all.
    ctx.Students.Add(stu);           

    ctx.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

那样就可以了-将一个新的学生插入您的数据库表中,并在学生与其科目之间建立1:n关系。