【问题标题】:Entity Framework duplicate primary key实体框架重复主键
【发布时间】:2016-11-13 07:08:06
【问题描述】:

我正在使用 Entity Framework 6 和 sqlite 来存储和检索一些数据。当以下代码块运行时,db.SaveChanges() 上会引发异常。

using (var db = new RepoDatabase(DBPath))
{
    var folder1 = new Folder
    {
        Name = "name1",
        Subtitle = "subtitle",
        ParentFolder = null,
        IsHidden = false,
        IsSimple = true,
        QueryOrFilePath = "query"
    };

    var folder2 = new Folder
    {
        Name = "name2",
        Subtitle = "subtitle",
        ParentFolder = folder1,
        IsHidden = false,
        IsSimple = true,
        QueryOrFilePath = "query"
    };
    db.Folders.Add(folder1);
    db.Folders.Add(folder2);
    db.SaveChanges();
}

例外:

在EntityFramework.dll中发生'System.Data.Entity.Infrastructure.DbUpdateException'

附加信息:无法确定“RhythmRepository.Folder_ParentFolder”关系的主体端。多个添加的实体可能具有相同的主键。

据我了解,当ID直接用于外键时经常会出现这个问题,但这里似乎不是这种情况,因为“ParentFolder”的类型是“Folder”。

文件夹类型在数据库中设置为自增,具有属性:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)] 

底层实体结构:

class Folder
{
    #region database fields
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int FolderID { get; set; }
    public string Name { get; set; }
    public string Subtitle { get; set; }
    [ForeignKey("FolderID")]
    public Folder ParentFolder { get; set; }
    public bool IsHidden { get; set; }
    public bool IsSimple { get; set; }
    public string QueryOrFilePath { get; set; }
    #endregion
}

以及创建表的 SQL 查询:

CREATE TABLE IF NOT EXISTS Folders 
(
    FolderID INTEGER PRIMARY KEY AUTOINCREMENT,
    Name varchar(255) NOT NULL,
    Subtitle varchar(255) NULL,
    ParentFolderID INT NULL,
    IsHidden BIT NOT NULL,
    IsSimple BIT NOT NULL,
    QueryOrFilePath varchar(255) NOT NULL,
    FOREIGN KEY (ParentFolderID) REFERENCES Folders(FolderID)
);

【问题讨论】:

  • 自加入Folder-Parentfolder的映射是什么?在一对一中,PK用作FK,由于显而易见的原因,这在这种情况下不起作用。
  • 这是一对多的关系。文件夹具有对其父级的引用,并且许多文件夹可以共享同一个父级。
  • 值得分享实体结构以及您如何定义关系映射。
  • 已添加。我不确定最初是否需要它们。

标签: c# entity-framework sqlite


【解决方案1】:

错误在零件中

[ForeignKey("FolderID")]
public Folder ParentFolder { get; set; }

这使 EF 认为 FolderID 是父 Folder 的外键。实际上,它是ParentFolderID。因此,将您的类定义和映射更改为

class Folder
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int FolderID { get; set; }

    public int? ParentFolderID { get; set; }
    [ForeignKey("ParentFolderID")]
    public Folder ParentFolder { get; set; }

    ...
}

如果 FolderID 是外键,EF 会得出结论,文件夹与其父文件夹之间存在 1:1 关联。通常,1:1 关联是由主键实现的,主键也是父键的外键。即孩子的主键复制其父母的主键。当 parent 和 child 是同一个实体类时,同一张表的两条记录必须具有相同的主键--不可能。

【讨论】:

  • 我以为外键属性是为了告诉EF对应表的哪一列是主键。您建议的更改是有道理的,但即使在实施后,我仍然在同一个地方遇到同样的异常。
  • 这几乎是整个解决方案。缺少的部分是 ParentFolderID 必须是 int 类型?而不是int。一旦进行了两组更改,一切都会完美运行
猜你喜欢
  • 2020-07-21
  • 2018-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多