繁体   English   中英

将数据插入作为主键外键一部分的表中 - 实体框架

[英]Insert data into table which have as part of primary key foreign key - Entity Framework

我正在尝试写入一个具有两部分主键的表。 其中一个是来自另一个表的外主键。 我能够创建这个表,但不能插入。

我正在使用实体框架 6.4.0

我的数据库是由以下代码创建的:

class School
{
      public int Id { get; set; }
      public string Name { get; set; }
      public List<Classroom> Classrooms { get; set; }
}

class Classroom
{
      [Key]
      [Column(Order = 0)]
      public int Id { get; set; }

      [Key]
      [Column(Order = 1)]
      [ForeignKey("School")]
      public int SchoolId { get; set; }
      public School School { get; set; }
      public string Name { get; set; }
}

class TestDbContext : DbContext
{
      public DbSet<School> Schools { get; set; }
      public DbSet<Classroom> Classrooms { get; set; }
} 

如何在Classrooms表中插入数据? 我试过这个(学校名称: schoolName在 db 中):

var context = new TestDbContext();`

var school = context.Schools.FirstOrDefault(s => s.Name == "SchoolName");
context.Classrooms.Add(new Classroom() {Name = "5B", School = school});
context.SaveChanges();

此代码的结果是此错误:

当 IDENTITY_INSERT 设置为 OFF 时,无法为表 'Classrooms' 中的标识列插入显式值。

看起来您的表Classroom中构成主键的两列之一是IDENTITY列 - 我猜是Id

您需要使用数据注释来装饰该列,以告诉 EF 这是一个 Identity 列,并且您不会为其提供任何值:

class Classroom
{
      [Key]
      [Column(Order = 0)]
      [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
      public int Id { get; set; }
      ....
}

这应该可以解决您的问题。 但是:如果这是一个身份列 - 那么你为什么要与SchoolId一起创建一个复合 PK? 这似乎完全没有必要,因为单独的Id列已经是您的 PK - 它唯一且可靠地标识了 eac 和表中的每一行.....

我想你需要的是ExecuteStoreCommand

public int ExecuteStoreCommand (string commandText, params object[] 参数);

在将记录添加到Classrooms之前尝试此操作:

context.ExecuteStoreCommand("SET IDENTITY_INSERT [dbo].[Classrooms] ON");

默认情况下,EF 将Id属性视为identity列。 正如@marc_s 所指出的,将复合键与标识列结合是没有意义的,所以如果您的Id不是标识列,那么您需要明确说明它:

class Classroom
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }

    // ...other properties..
}

暂无
暂无

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

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