为了账号安全,请及时绑定邮箱和手机立即绑定

更新时违反实体核心的PRIMARY KEY约束错误

更新时违反实体核心的PRIMARY KEY约束错误

C#
料青山看我应如是 2021-04-14 09:15:27
在书籍和作者之间通常存在许多对许多的关系。尝试更新作者时出现错误。错误的全名是“ SqlException:违反主键约束'PK_BookAuthor'。无法在对象'dbo.BookAuthor'中插入重复键。重复键值为(2,2)。”。如果我不使用UpdateAssociatedObject函数,则一切正常。但是,如果使用它,则在尝试保存更改时会收到错误消息。 var parseBook = Mapper.Map<BookViewModel, Book>(viewModel);        Book viewModelBook = parseBook;        var book = db.Books.FindOne(viewModel.BookId);        book.BookId = viewModelBook.BookId;        book.BookName = viewModelBook.BookName;        book.Genre = viewModelBook.Genre;        book.Pages = viewModelBook.Pages;        book.Publisher = viewModelBook.Publisher;        db.SaveChanges();        UpdateAssociatedObject(book, viewModelBook);    }    public void UpdateAssociatedObject(Book bookForUpdate, Book book)    {        bookForUpdate.BookAuthors = book.BookAuthors;    //error is here        db.SaveChanges();    }映射后viewModelBook的值: 模型(为简洁起见,删除了一些属性) public class Book{    public int BookId { get; set; }    public List<BookAuthor> BookAuthors { get; set; }}public class Author    {        public int AuthorId { get; set; }        public string AuthorName { get; set; }        public List<BookAuthor> BookAuthors { get; set; }    } public class BookAuthor{    public int BookId { get; set; }    public Book Book { get; set; }    public int AuthorId { get; set; }    public Author Author { get; set; }}public class BookViewModel{    public int BookId { get; set; }    public virtual List<AuthorViewModel> Authors { get; set; }    }public class AuthorViewModel    {        public int AuthorId { get; set; }        public string AuthorName { get; set; }    }UPD:创建书籍后,BookId会跳(以1000为步长)。将Include()添加到Find方法后,错误更改为System.InvalidOperationException:无法跟踪实体类型'BookAuthor'的实例,因为已经跟踪了另一个具有相同的{'BookId','AuthorId'}关键字值的实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。考虑使用'DbContextOptionsBuilder.EnableSensitiveDataLogging'来查看冲突的键值。
查看完整描述

2 回答

?
湖上湖

TA贡献2003条经验 获得超2个赞

终于成功了!在下面,您可以看到与原始代码的不同之处。


PS也许您知道Remove方法更好的算法,如果可以在注释中键入它,那么我将更改答案。


BookRepository:


 public Book Find(int id)

    {

        Book searchedBook = db.Books

          .Include(b => b.BookAuthors)

          .ThenInclude(b => b.Author)

          .SingleOrDefault(b => b.BookId == id);


        return searchedBook;

    }

BookService:


public void UpdateObject(BookViewModel viewModel)

        {

            Book parsedBook = Mapper.Map<BookViewModel, Book>(viewModel);

            //Book viewModelBook = parseBook;

            var book = db.Books.Find(viewModel.BookId);

            book.BookId = parsedBook.BookId;

            book.BookName = parsedBook.BookName;

            book.Genre = parsedBook.Genre;

            book.Pages = parsedBook.Pages;

            book.Publisher = parsedBook.Publisher;

            UpdateAssociatedObject(book, parsedBook);

        }

public void UpdateAssociatedObject(Book bookToUpdate, Book viewModelBook)

        {

            AddUpdatedAuthors(bookToUpdate, viewModelBook);

            RemoveUpdatedAuthors(bookToUpdate, viewModelBook);

            db.SaveChanges();

        }

     private void AddUpdatedAuthors(Book bookToUpdate, Book viewModelBook)

        {

            foreach (var authors in viewModelBook.BookAuthors)

            {

                var searchBookAuthor = bookToUpdate.BookAuthors.Find(b => b.AuthorId == authors.AuthorId);

                if (searchBookAuthor == null)

                {

                    bookToUpdate.BookAuthors.Add(authors);

                }

            }

        }

        private void RemoveUpdatedAuthors(Book bookToUpdate, Book viewModelBook)

        {

            int countOfAuthors = bookToUpdate.BookAuthors.Count;

            for (int i = 0; i < countOfAuthors; i++)

            {

                BookAuthor searchBookAuthor = null;

                foreach (var viewModelAuthors in viewModelBook.BookAuthors)

                {

                    if (viewModelAuthors.AuthorId == bookToUpdate.BookAuthors[i].AuthorId)

                    {

                        searchBookAuthor = viewModelAuthors;

                    }

                }

                if (searchBookAuthor == null)

                {

                    bookToUpdate.BookAuthors.Remove(bookToUpdate.BookAuthors[i]);

                    i--;

                    countOfAuthors--;

                }

            }

        }


查看完整回答
反对 回复 2021-04-24
?
婷婷同学_

TA贡献1844条经验 获得超8个赞

该问题出现在db.SaveChanges()中。您在相同的上下文中多次调用db.SaveChanges

db.SaveChanges();
UpdateAssociatedObject(book, viewModelBook);

然后UpdateAssociatedObject(book, viewModelBook); 尝试删除一个db.SaveChanges()。


查看完整回答
反对 回复 2021-04-24
  • 2 回答
  • 0 关注
  • 359 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信