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

在书籍和作者之间通常存在许多对许多的关系。尝试更新作者时出现错误。错误的全名是“ 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的值: 模型(为简洁起见,删除了一些属性)

http://img4.mukewang.com/60837b200001f2ff05490164.jpg

 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'来查看冲突的键值。


料青山看我应如是
浏览 360回答 2
2回答

湖上湖

终于成功了!在下面,您可以看到与原始代码的不同之处。PS也许您知道Remove方法更好的算法,如果可以在注释中键入它,那么我将更改答案。BookRepository:&nbsp;public Book Find(int id)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Book searchedBook = db.Books&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Include(b => b.BookAuthors)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .ThenInclude(b => b.Author)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .SingleOrDefault(b => b.BookId == id);&nbsp; &nbsp; &nbsp; &nbsp; return searchedBook;&nbsp; &nbsp; }BookService:public void UpdateObject(BookViewModel viewModel)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Book parsedBook = Mapper.Map<BookViewModel, Book>(viewModel);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Book viewModelBook = parseBook;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var book = db.Books.Find(viewModel.BookId);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; book.BookId = parsedBook.BookId;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; book.BookName = parsedBook.BookName;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; book.Genre = parsedBook.Genre;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; book.Pages = parsedBook.Pages;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; book.Publisher = parsedBook.Publisher;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UpdateAssociatedObject(book, parsedBook);&nbsp; &nbsp; &nbsp; &nbsp; }public void UpdateAssociatedObject(Book bookToUpdate, Book viewModelBook)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AddUpdatedAuthors(bookToUpdate, viewModelBook);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RemoveUpdatedAuthors(bookToUpdate, viewModelBook);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; db.SaveChanges();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp;private void AddUpdatedAuthors(Book bookToUpdate, Book viewModelBook)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; foreach (var authors in viewModelBook.BookAuthors)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var searchBookAuthor = bookToUpdate.BookAuthors.Find(b => b.AuthorId == authors.AuthorId);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (searchBookAuthor == null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bookToUpdate.BookAuthors.Add(authors);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; private void RemoveUpdatedAuthors(Book bookToUpdate, Book viewModelBook)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int countOfAuthors = bookToUpdate.BookAuthors.Count;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < countOfAuthors; i++)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BookAuthor searchBookAuthor = null;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; foreach (var viewModelAuthors in viewModelBook.BookAuthors)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (viewModelAuthors.AuthorId == bookToUpdate.BookAuthors[i].AuthorId)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; searchBookAuthor = viewModelAuthors;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (searchBookAuthor == null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bookToUpdate.BookAuthors.Remove(bookToUpdate.BookAuthors[i]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i--;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; countOfAuthors--;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }

婷婷同学_

该问题出现在db.SaveChanges()中。您在相同的上下文中多次调用db.SaveChangesdb.SaveChanges(); UpdateAssociatedObject(book,&nbsp;viewModelBook);然后UpdateAssociatedObject(book, viewModelBook);&nbsp;尝试删除一个db.SaveChanges()。
打开App,查看更多内容
随时随地看视频慕课网APP