【问题标题】:EF6 SqlException: Violation of PRIMARY KEY constraint ... The duplicate key value is (0)EF6 SqlException:违反 PRIMARY KEY 约束...重复键值为 (0)
【发布时间】:2019-02-10 09:10:36
【问题描述】:

我知道 SQL,但我对 ORM 非常陌生,并且在 VS 2017 中使用 EntityFramework 6.2.0 在沙盒中玩游戏。 我认为该框架应该使我能够或多或少地像使用 POCO 对象一样进行编码,而无需处理主键/外键。 只要我在下面的代码 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]

我从数据库中创建了模型。

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

     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:违反主键约束“PK_WorkingHours”。无法在对象“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; }
}

【问题讨论】:

  • 将您的 Person WorkingHour 模型类添加到问题中。
  • WorkingHours 不是 IDENTITY(1,1) 并且它没有在你的代码中更新,所以它总是 0
  • @Caramiriel 是的!这是另一个问题。
  • 已解决@Caramiriel,您的评论就是解决方案。我错过了 WorkingHours 表中的 IDENTITY(1,1) !
  • @BitLauncher 正如我解释的那样,您还两次将相同的实体添加到上下文问题中。

标签: c# visual-studio-2017 entity-framework-6 sqlexception


【解决方案1】:

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

所以将Id 列设为WorkingHour [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

在这里,您在上下文中添加了两次WorkingHour。一个带有Person 实体,另一个是单独的。所以删除第二组,只使用第一组,如下所示:

person2.WorkingHours.Add(workingHour1); 
person1.WorkingHours.Add(workingHour2);

【讨论】:

  • 等待更新我的答案。
  • @BitLauncher 检查我更新的答案。希望现在它能解决您的问题。
  • 解决方案是在 WorkingHours 中缺少 IDENTITY(1,1)。但是你提到的两行是完全冗余的。我现在尝试了这两行,结果是一样的。但我不想编写多余的代码,让下一个阅读我代码的程序员感到困惑——谢谢你的提示。
  • @BitLauncher 顺便问一下,您是否检查过它没有向数据库添加两次工作时间(有冗余)?
【解决方案2】:

我认为你的问题是因为[WorkingHours]中的[Id]

  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]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-30
    • 2020-09-17
    • 1970-01-01
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多