【问题标题】:EF vs EF Core on Saving Related Entities关于保存相关实体的 EF 与 EF Core
【发布时间】:2021-05-21 20:25:47
【问题描述】:

我有两个相关的实体,如下所示

public partial class Student{
   public int StudentId{ get; set; }
   public string Name{ get; set; }
   public ICollection<Subject> Subjects{get;set;}
}

public partial class Subject{
   public int SubjectId{ get; set; }
   public int StudentId{ get; set; }
   public string SubjectName{ get; set; }
   public Student Student{ get; set; }
}

在 EF6 中,我可以按如下方式保存这些相关对象并且工作正常。

var student = new Student{
Name = "John Doe"
}

_dbContext.Sudents.Add(student);

var subjects = new List<Subject>{
new Subject{StudentId = student.StudentId, SubjectName = "Math"},
new Subject{StudentId = student.StudentId, SubjectName = "Biology"}
}

_dbContext.Subjects.AddRange(subjects);

_dbContext.SaveChanges();

上述代码在 EF Core 中不起作用,因为 Subject 实体中的 StudentId 始终没有价值。

为了能够保存在 EF Core 中,我必须如下所示

var subjects = new List<Subject>{
new Subject{SubjectName = "Math"},
new Subject{SubjectName = "Biology"}
}

var student = new Student{
Name = "John Doe",
Subjects = subjects
}

_dbContext.Sudents.Add(student);

_dbContext.SaveChanges();

EF Core 中发生了哪些更改,因此我必须更改语法才能保存这些相关实体?

提前致谢

【问题讨论】:

    标签: c# entity-framework .net-core entity-framework-core navigational-properties


    【解决方案1】:

    您无法仅通过将学生添加到上下文中来获取 StudentId。只有在运行 SaveChanges 后才能获取密钥。这就是为什么您的第一个示例无法正常工作的原因。但是如果你把代码改成这个就可以了

    var student = new Student{
    Name = "John Doe"
    }
    
    _dbContext.Sudents.Add(student);
    _dbContext.SaveChanges();
    
    var subjects = new List<Subject>{
    new Subject{StudentId = student.StudentId, SubjectName = "Math"},
    new Subject{StudentId = student.StudentId, SubjectName = "Biology"}
    }
    
    _dbContext.Subjects.AddRange(subjects);
    _dbContext.SaveChanges();
    

    或者(感谢@SvyatoslavDanyliv 的提示)您可以尝试分配整个学生实例而不是 studentId

    var student = new Student{
    Name = "John Doe"
    }
    
    var subjects = new List<Subject>{
    new Subject{Student=student, SubjectName = "Math"},
    new Subject{Student = student, SubjectName = "Biology"}
    }
    
    _dbContext.Subjects.AddRange(subjects);
    _dbContext.SaveChanges();
    

    在这种情况下,您也只能调用 SaveChanges 一次。

    【讨论】:

    • 我没有使用过 EF Core,但我很确定你说的不正确。 EF 足够聪明,可以在同一个操作中完成所有这些操作。否则,如果您要求这两个更改必须完成或完全失败,这将变得非常复杂。
    • 很抱歉,您应该仔细阅读。 PO 的方式#2 展示了如何在相同的操作中做到这一点。只有两种不同的算法。我的回答是关于方式#1 不起作用的原因。
    • 只需分配 Student 属性而不是 StudentId。
    • 我理解EF默认执行数据库事务。通过添加 Student 实体并在以下对象上使用它的主键,可以在 EF6 上完美运行(我在生产环境中运行代码)。我仍然不明白为什么相同的算法在 EF Core 上不起作用。 EF Core 有变化还是 EF6 上的错误?谢谢
    猜你喜欢
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2020-09-04
    • 2017-11-07
    • 2018-02-12
    • 2020-04-09
    • 2021-03-27
    • 1970-01-01
    相关资源
    最近更新 更多