【发布时间】:2021-02-10 18:06:49
【问题描述】:
我试图解决这个问题好几个小时。我相信这是某种关系问题。
我收到此错误:
DELETE 语句与 REFERENCE 约束“FK_NoteTag”冲突 _Notes_NoteId”。数据库“db”,表“dbo.NoteTag”,列“NoteId”发生冲突。
这些是我的模型类:
public class Group
{
public Group()
{ }
public Group(int groupId, string groupName)
{
GroupId = groupId;
GroupName = groupName;
}
[Key]
public int? GroupId { get; set; }
[Required]
public string GroupName { get; set; }
public virtual User User { get; set; }
public virtual List<Note> Notes { get; set; }
public virtual IList<GroupTag> GroupTag { get; set; }
}
public class GroupTag
{
public GroupTag()
{ }
public GroupTag(int groupId, Group group, int tagId, Tag tag)
{
GroupId = groupId;
Group = group;
TagId = tagId;
Tag = tag;
}
public virtual int? GroupId { get; set; }
public virtual Group Group { get; set; }
public virtual int? TagId { get; set; }
public virtual Tag Tag { get; set; }
}
public class Note
{
public Note()
{ }
public Note(int noteId, string noteName, string noteText, DateTime noteDuration, DateTime noteCreation)
{
NoteId = noteId;
NoteName = noteName;
NoteText = noteText;
NoteDuration = noteDuration;
NoteCreation = noteCreation;
}
[Key]
public int? NoteId { get; set; }
[Required]
public string NoteName { get; set; }
public string NoteText { get; set; }
public DateTime NoteDuration { get; set; }
public DateTime NoteCreation { get; set; }
public virtual Group Group { get; set; }
public virtual IList<NoteTag> NoteTag { get; set; }
}
public class NoteTag
{
public NoteTag()
{ }
public NoteTag(int noteId, Note note, int tagId, Tag tag)
{
NoteId = noteId;
Note = note;
TagId = tagId;
Tag = tag;
}
public virtual int? NoteId { get; set; }
public virtual Note Note { get; set; }
public virtual int? TagId { get; set; }
public virtual Tag Tag { get; set; }
}
public class Tag
{
public Tag()
{ }
public Tag(int tagId, string tagName)
{
TagId = tagId;
TagName = tagName;
}
[Key]
public int? TagId { get; set; }
[Required]
public string TagName { get; set; }
// owner
public virtual User User { get; set; }
public virtual IList<NoteTag> NoteTag { get; set; }
public virtual IList<GroupTag> GroupTag { get; set; }
}
public class User
{
public User()
{ }
public User(int userId, string nickname, string password, bool admin)
{
UserId = userId;
Nickname = nickname;
Password = password;
Admin = admin;
}
[Key]
public int? UserId { get; set; }
[Required]
public string Nickname { get; set; }
[Required]
public string Password { get; set; }
[Required]
public bool Admin { get; set; }
public virtual List<Tag> Tags { get; set; }
public virtual IList<Group> Groups { get; set; }
}
这里是数据库上下文:
//M:M keys (1/3) NoteTag
modelBuilder.Entity<NoteTag>().HasKey(nt => new {nt.NoteId, nt.TagId});
//M:M keys (2/3)
modelBuilder.Entity<NoteTag>()
.HasOne<Note>(nt => nt.Note)
.WithMany(t => t.NoteTag)
.OnDelete(DeleteBehavior.ClientSetNull);
//M:M keys (3/3)
modelBuilder.Entity<NoteTag>()
.HasOne<Tag>(nt => nt.Tag)
.WithMany(n => n.NoteTag)
.OnDelete(DeleteBehavior.ClientSetNull);
//
//M:M keys (1/3) GroupTag
modelBuilder.Entity<GroupTag>().HasKey(gt => new {gt.GroupId, gt.TagId});
//M:M (2/3)
modelBuilder.Entity<GroupTag>()
.HasOne<Group>(gt => gt.Group)
.WithMany(t => t.GroupTag)
.OnDelete(DeleteBehavior.ClientSetNull);
//M:M (3/3)
modelBuilder.Entity<GroupTag>()
.HasOne<Tag>(gt => gt.Tag)
.WithMany(g => g.GroupTag)
.OnDelete(DeleteBehavior.ClientSetNull);
modelBuilder.Entity<Group>()
.HasMany(g => g.Notes)
.WithOne(u => u.Group)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<User>()
.HasMany(u => u.Groups)
.WithOne(g => g.User)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<User>()
.HasMany(u => u.Tags)
.WithOne(g => g.User)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Note>()
.HasData(
notes
);
modelBuilder.Entity<Tag>()
.HasData(
tags
);
modelBuilder.Entity<User>()
.HasData(
users
);
modelBuilder.Entity<Group>()
.HasData(
groups
);
modelBuilder.Entity<NoteTag>()
.HasData(
noteTag
);
modelBuilder.Entity<GroupTag>()
.HasData(
groupTag
);
这是 DB 的种子:
object[] users =
{
new
{
UserId = 1, Nickname = "AwesomeUser", Password = "nicepass", Admin = true
},
new
{
UserId = 2, Nickname = "LameUser", Password = "nopass", Admin = false
},
new
{
UserId = 3, Nickname = "scooby", Password = "pass", Admin = false
},
new
{
UserId = 4, Nickname = "doo", Password = "hezogeg", Admin = false
}
};
object[] groups =
{
new {GroupId = 1, GroupName = "leden", UserId = 1},
new {GroupId = 2, GroupName = "unor", UserId = 2},
new {GroupId = 3, GroupName = "brezen", UserId = 3},
new {GroupId = 4, GroupName = "duben", UserId = 4}
};
object[] notes =
{
new
{
NoteId = 1,
NoteName = "Uvařit oběd",
NoteText = "1. Brambory 2. maso",
NoteDuration = DateTime.Now,
NoteCreation = new DateTime(2008, 3, 1, 7, 0, 0),
GroupId = 1
},
new
{
NoteId = 2,
NoteName = "Naučit se programova",
NoteText = "- sjet C# tutorial",
NoteDuration = DateTime.Now,
NoteCreation = new DateTime(2020, 3, 1, 7, 0, 0),
GroupId = 2
},
new
{
NoteId = 3,
NoteName = "B7",
NoteText = "Vyjít lysou",
NoteDuration = DateTime.Now,
NoteCreation = new DateTime(2018, 3, 1, 7, 0, 0),
GroupId = 3
},
new
{
NoteId = 4,
NoteName = "B12",
NoteText = "Udělat salto",
NoteDuration = DateTime.Now,
NoteCreation = new DateTime(2019, 3, 1, 7, 0, 0),
GroupId = 4
}
};
object[] tags =
{
new {TagId = 1, TagName = "Vaření", UserId = 1},
new {TagId = 2, TagName = "Sport", UserId = 2},
new {TagId = 3, TagName = "Sebe vyvoj", UserId = 3},
new {TagId = 4, TagName = "Gymnastika", UserId = 4}
};
object[] noteTag =
{
new {NoteId = 1, TagId = 1},
new {NoteId = 2, TagId = 2},
new {NoteId = 3, TagId = 3},
new {NoteId = 4, TagId = 4}
};
object[] groupTag =
{
new {GroupId = 1, TagId = 1},
new {GroupId = 2, TagId = 2},
new {GroupId = 3, TagId = 3},
new {GroupId = 4, TagId = 4}
};
感谢您的帮助
【问题讨论】:
-
一次检查数据库表中的主键和外键关系。
-
"我相信这是某种关系问题"...是的。在关系数据库中,如果有外键链接到该表中的列,并且该列中的值正在链接表中使用,则无法从表中删除行。因为如果你这样做了,另一个表将失去其完整性 - 没有任何价值可以重新加入,以使记录有意义。这就是此类约束的全部意义,以阻止您删除其他表所需的数据。如果您不了解这些关键思想,我建议您花一些时间了解有关此主题的更多信息。
-
@ADyson 我建议添加级联删除行为应该可以解决这个问题。所以它会先从外部表中删除数据,然后从它自己的第一个表中删除。在那种情况下,问题在于行为的错误实施,对吗?还是问题的根源在其他地方?
-
添加级联删除行为应该有助于解决这个问题。您尚未将其添加到错误中提到的表中。
标签: c# sql asp.net-core database-design ef-fluent-api