2
votes

Problem: I'm trying to save a list of objects into the database, using the AddRange.

The Setup: I have a database of two tables:

BookTitles:
- Book_Id
- BookName

BookAuthors:
- Author_Id
- AuthorName
- Book_Id

In the BookAuthors table, the "Book_Id" is the Foreign Key from BookTitles table. I Use Entity Framework, Database First. EF created the models for me, so the model of BookTitles looks like this:

public partial class BookTitles
{
    public BookTitles()
    { this.BookAuthors = new HashSet<BookAuthors>(); }

    public int Book_Id { get; set; }
    public string BookName { get; set; }

    public virtual ICollection<BookAuthors> BookAuthors { get; set; }
}

THE WAY IT WORKS: If i use this function to add one Book record (which will contain a list of BookAuthors) to the database, it works fine. And the Function below will add one record to the BookTitles table, and thwo record to the BookAuthors table. Here I use the "Add" method:

private static void InsertBook()
{
    using (var db = new BooksContext())
    {
        var authors = new List<BookAuthors>()
        {
            new BookAuthors() {AuthorName = "Author 1"},
            new BookAuthors() {AuthorName = "Author 2"}
        };

        var book = new BookTitles {BookName = "Book1", BookAuthors = authors};

        db.BookTitles.Add(book);
        db.SaveChanges();
     }
 }

THE WAY IT DOESN'T WORK: If i try to add a list of Books to the database, using the AddRange(), it will throw an error "Collection was modified; enumeration operation may not execute":

private static void AddRangeOfBooks()
{
    using (var db = new BooksContext())
    {
        var listOfAuthors = new List<BookAuthors>
        {
            new BookAuthors() {AuthorName = "Author1"},
            new BookAuthors() {AuthorName = "Author2"}
        };

        var listOfBooks = new List<BookTitles>
        {
            new BookTitles() {BookName = "Book 1", BookAuthors = listOfAuthors},
            new BookTitles() {BookName = "Book 2", BookAuthors = listOfAuthors}
        };

        db.BookTitles.AddRange(listOfBooks);
        db.SaveChanges();
    }
}

Why it throws the error? Why does it work with Add() method (adding a single record) and doesn't work with AddRange() (adding a range of records)?

1

1 Answers

9
votes

You can not use the same collection in different entities, try:

var listOfBooks = new List<BookTitles>
{
    new BookTitles() {BookName = "Book 1", BookAuthors = listOfAuthors},
    new BookTitles() {BookName = "Book 2", BookAuthors = listOfAuthors.ToList()}
};

The important part is the ToList(). I have faced some similar issue and i think this have to solve the problem becouse EF using hashset to keep tracking of every objects as well as collection. If you put the same collection into different entities the framework will not know where it belongs.