【问题标题】:FK constraint at SaveChange()SaveChange() 处的 FK 约束
【发布时间】:2016-10-09 10:47:56
【问题描述】:

学习EF6 code-first。按照外键约定,我会将 StandardId 作为学生表的 FK,而不是丑陋的 Standards_StandardId。即使我逐字逐句地按照教程进行操作,但在更新 ctx.SaveChanges() 的数据库时遇到了异常。

我认为我的实体框架的某些约定无法正常工作。所以我在public Standard Part { get; set; } 上尝试了DataAnnotation [ForeignKey("StandardId")] 来覆盖FK。但我仍然收到完全相同的错误!

我的 SQL Server 是否“未与”我的实体框架“对话”,或者某些内容已损坏?以下是详细的所有代码和错误消息:

实体模型

public class Student {
    public Student() { }
    public int StudentID { get; set; }
    public string StudentName { get; set; }

    //Foreign key for Standard
    public int StandardId { get; set; } <- StandardId, not Standard_StandardId
    public Standard Standard { get; set; } }

public class Standard {
    public Standard() { }
    public int StandardId { get; set; }
    public string StandardName { get; set; } 
    public ICollection<Student> Students { get; set; } }

DbContext 和 DbSet

namespace EF_Code_First_Tutorials {
    public class SchoolContext: DbContext {
        public SchoolContext(): base() { }
        public DbSet<Student> Students { get; set; }
        public DbSet<Standard> Standards { get; set; } } }

主要

class Program {
    static void Main(string[] args) {
        using (var ctx = new SchoolContext()) {
            Student stud = new Student() { StudentName = "New Student" };  
            ctx.Students.Add(stud);
            ctx.SaveChanges(); } } } <-- ERROR!

在 Visual Studio 中

类型异常 'System.Data.Entity.Infrastructure.DbUpdateException' 发生在 EntityFramework.dll 但未在用户代码中处理

InnerException

{"INSERT 语句与 FOREIGN KEY 约束冲突 \"FK_dbo.Students_dbo.Standards_StandardId\"。冲突发生在 数据库“EF_Code_First_Tutorials.SchoolContext”,表 \"dbo.Standards\",列 'StandardId'。\r\n该语句已 终止。”}

【问题讨论】:

  • 如果我删除 public int StandardId { get; set; } 并使用默认的 Standards_StandardId,那么它可以工作。但我更喜欢 FK 与其相关的主键(StandardId)同名。

标签: c# entity-framework code-first


【解决方案1】:

StudentStandard 之间的关系不是可选的,它是必需的。这意味着,当您保存 Student 时,必须将 StandardId 分配给现有的 Standard 记录的 ID。

编辑

因此,您的程序应该包括Standard 对象的创建:

class Program {
    static void Main(string[] args) {
        using (var ctx = new SchoolContext()) {
            Student stud = new Student() { StudentName = "New Student" };  
            ctx.Students.Add(stud);
            Standard stan = new Standard { StandardId = 524 };
            stud.StantardId = stan.StandardId;
            ctx.Standards.Add(stan);
            ctx.SaveChanges(); } } }

如果你想让关系成为可选的,Student 应该有

public int? StandardId { get; set; }

代替:

public int StandardId { get; set; }

【讨论】:

  • 现在可以使用了。除了当我浏览 SSMS 中的行时,我看到 SSMS 在移动悬停时带有红色下划线StandardId,它显示Invalid column name 'StandardId'。我的代码似乎都可以正常工作,只是想知道为什么 SSMS 在 SQL 脚本窗口中将其下划线表示为无效。
  • 您对 DB 的查询仍然执行吗?如果是,那么暂时忽略该错误,SSMS 有时会像那样发疯。我不知道原因,所以你必须多搜索一下才能用 SSMS 解决这个问题。
  • 谢谢。查询在 DB 中执行得很好。 SSMS 只是用红色强调它。我将对其进行研究或将其作为新问题发布。
  • 原来神秘的下划线是由于 Intellisense 缓存造成的。见SO: Invalid column but still working
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-16
  • 1970-01-01
相关资源
最近更新 更多