【问题标题】:ASP.NET Core - the DELETE statement conflicted with the REFERENCE constraint . The conflict occurred in databaseASP.NET Core - DELETE 语句与 REFERENCE 约束冲突。数据库发生冲突
【发布时间】: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


【解决方案1】:

我终于找到了问题...我需要外键规范。我认为流利的 api 自然地解决了。谢谢各位

【讨论】:

    猜你喜欢
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    相关资源
    最近更新 更多