代码之家  ›  专栏  ›  技术社区  ›  BitLauncher

EF6 SQLException:违反主键约束…重复的键值为(0)

  •  0
  • BitLauncher  · 技术社区  · 6 年前

    我知道SQL,但我对ORM非常陌生,在2017年和2017年使用EntityFramework 6.2.0在沙箱中玩游戏。 我认为框架应该使我能够或多或少地像使用POCO对象那样编写代码,而不必处理主键/外键。 当我调用下面的code context.savechanges()时,这些更改就保存在数据库中; 我对EF6及其文档还不了解什么?

    我用一个外键和一个1:N关系创建了两个表Person和WorkingHours。

      CREATE TABLE [dbo].[Person](
        [FirstName] [nvarchar](100) NOT NULL,
        [LastName] [nvarchar](100) NOT NULL,
        [BirthDate] [date] NULL,
        [Id] [int] IDENTITY(1,1) NOT NULL,
     CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED 
    (
        [Id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    
    CREATE TABLE [dbo].[WorkingHours](
      [Id] [int] NOT NULL,
      [PersonId] [int] NOT NULL,
      [Date] [date] NOT NULL,
      [Start] [time](7) NOT NULL,
      [Hours] [real] NOT NULL,
     CONSTRAINT [PK_WorkingHours] PRIMARY KEY CLUSTERED 
    (
      [Id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    

    我从数据库创建了模型。

    我尝试创建两个人条目,每个条目都有一个工作时间条目,并将其立即保存到数据库中。 代码如下:

         static void Main(string[] args)
        {
            using(var context = new EntityFrameworkTrialEntities2())
            {
                 // Inserting entries
                var person1 = new Person() { FirstName = "Al", LastName = "Curie", BirthDate = new DateTime(1867, 11, 7) };
                var person2 = new Person() { FirstName = "Al", LastName = "Capone", BirthDate = new DateTime(1899, 1, 7) };
                context.Person.Add(person1);
                context.Person.Add(person2);
    
                var workingHour1 = new WorkingHour() { Date = new DateTime(1887, 8, 18), Start = new TimeSpan(6, 35, 33), Hours = 4.3F };
                var workingHour2 = new WorkingHour() { Date = new DateTime(1919, 9, 19), Start = new TimeSpan(10, 23, 56), Hours = 3.2F };
                person2.WorkingHours.Add(workingHour1); 
                person1.WorkingHours.Add(workingHour2); 
    
                context.WorkingHours.Add(workingHour1);
                context.WorkingHours.Add(workingHour2);
                context.SaveChanges(); // <-- place of exeception !!!!!!!!!!!!!!!!!!!!
    
                // (next step as EF6 trial: here the previously intentionally mixed relationships between person1/2 and workingHour2/1 shall be corrected)
    

    但在调用context.savechanges()时,我得到了以下异常:

    SqlException:违反主键约束 “工作时间”。无法在对象“dbo.workinghours”中插入重复键。 重复的键值为(0)。 语句已终止。**

    我尝试了更多的context.savechanges()和attach()和其他命令,但总是失败,上面有例外。 context.configuration.proxyCreationEnabled默认设置为true。

    这里是模型类:

    public partial class Person
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Person()
        {
            this.WorkingHours = new HashSet<WorkingHour>();
        }
    
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public Nullable<System.DateTime> BirthDate { get; set; }
        public int Id { get; set; }
    
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<WorkingHour> WorkingHours { get; set; }
    }
    
    
    public partial class WorkingHour
    {
        public int Id { get; set; }
        public int PersonId { get; set; }
        public System.DateTime Date { get; set; }
        public System.TimeSpan Start { get; set; }
        public float Hours { get; set; }
    
        public virtual Person Person { get; set; }
    }
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   TanvirArjel    6 年前

    第一个问题是 主键 WorkingHour 不是 Identity Key 这就是为什么它总是被设置为 0 (默认值为 int 为每个 工作时间 因此它被复制了。

    所以做 Id 工作时间 [Id] [int] IDENTITY(1,1) NOT NULL

    第二个问题是以下几行:

    person2.WorkingHours.Add(workingHour1); // adding with person
    person1.WorkingHours.Add(workingHour2); // adding with person
    
    context.WorkingHours.Add(workingHour1); // adding individually
    context.WorkingHours.Add(workingHour2); // adding individually
    

    这是您添加的 工作时间 两次。一带 Person 实体和其他实体是单独的。因此,移除第二组,只需使用第一组,如下所示:

    person2.WorkingHours.Add(workingHour1); 
    person1.WorkingHours.Add(workingHour2);
    
        2
  •  1
  •   Amirhossein Yari    6 年前

    我认为你的问题是因为 [Id] 在里面 [WorkingHours] :

      CREATE TABLE [dbo].[WorkingHours](
          [Id] [int] NOT NULL,
          [PersonId] [int] NOT NULL,
          [Date] [date] NOT NULL,
          [Start] [time](7) NOT NULL,
          [Hours] [real] NOT NULL,
         CONSTRAINT [PK_WorkingHours] PRIMARY KEY CLUSTERED 
        (
          [Id] ASC
        )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
        ) ON [PRIMARY]
    

    请按以下方式更改,然后重试。

     CREATE TABLE [dbo].[WorkingHours](
          [Id] [int] IDENTITY(1,1) NOT NULL,
          [PersonId] [int] NOT NULL,
          [Date] [date] NOT NULL,
          [Start] [time](7) NOT NULL,
          [Hours] [real] NOT NULL,
         CONSTRAINT [PK_WorkingHours] PRIMARY KEY CLUSTERED 
        (
          [Id] ASC
        )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
        ) ON [PRIMARY]