我使用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();
}
例外:
' System.Data.Entity.Infrastructure.DbUpdateException'发生在EntityFramework.dll
中附加信息:无法确定' RhythmRepository.Folder_ParentFolder'的主要结尾。关系。多个添加的实体可能具有相同的主键。
根据我的理解,当ID直接用于外键时经常会出现这个问题,但这似乎不是这里的情况,因为" ParentFolder"是"文件夹"。
文件夹类型在数据库中设置为自动递增,并具有以下属性:
[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)
);
答案 0 :(得分:3)
错误发生在
部分[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关联由主键实现,主键也是父键的外键。即,孩子的主键复制其父键的主键。当父级和子级是同一个实体类时,同一个表的两个记录必须具有相同的主键 - 不可能。