4

just started learning Entity Framework 6 and am having trouble adding data from my web app to a MySQL database. I feel I'm doing everything right but I always get an "System.NullReferenceException: Object reference not set to an instance of an object" when I try to add something to the database using a Code First approach. The code is shown below.

Customer Class:

namespace LibraryManager.Models
{
     public class Customer
     {
        public int CustomerId { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public virtual ICollection<Book> BooksRead { get; set; }

        public Customer()
        {
            this.BooksRead = new List<Book>();
        }
    }
}

Book Class:

namespace LibraryManager.Models
{
    public class Book
    {
        public int BookId { get; set; }
        public string Name { get; set; }
        public string Genre { get; set; }
        public double Rating { get; set; }
        public Boolean Available { get; set; }
        public string Author { get; set; }
        public string Desc { get; set; }
        public virtual Customer Customer { get; set; }
    }
}

DatabaseManager

public class DatabaseManager
{

    /**
     * Adds a book into the database
     */
    public void AddBook(Book book)
    {
        using (var ctx = new DatabaseContext())
        {
            ctx.Books.Add(book); -->Error Occurs here
            ctx.SaveChanges();
        }
    }
}

Context Class

 public class DatabaseContext : DbContext
{
    public DbSet<Book> Books { get; set; }
    public DbSet<Customer> Customers { get; set; }

    public DatabaseContext() : base()
    {


    } 
}

Thanks in advance

EDIT:

Code calling AddBook

  Book HarryPotter = new Book() { Name = "Chamber of Secrets", Genre = "Fantasy", Rating = 8.6, Available = true, Author = "J.K Rowling" };
  DatabaseManager manager = new DatabaseManager();
  manager.AddBook(HarryPotter);
user7215621
  • 43
  • 1
  • 1
  • 4

1 Answers1

1

1st. Add a key attribute to your CustomerId and BookId properties. Your Customer property is null based on your code calling the method, so it's failing because it cant establish a foreign relationship with a null customer. So, either specify the customer in your constructor, or a null checker in your AddBook to check if Customer is null, and to create a new customer if so.

public void AddBook(Book book)
{
    using (var ctx = new DatabaseContext())
    {
        ctx.Books.Add(book);

        if (boot.Customer == null)
            book.Customer = new Customer();

        ctx.SaveChanges();
    }
}

However, you don't want to create a new customer for each book (i'm assuming), so require a customer in your book constructor, so the relationship can be established in the DB. It's also worth using a try/catch for error handling in your method to help you with debugging and tracing.

Ratatoskr
  • 149
  • 5
  • 1
    You do not need to add `[Key]` attributes for it to work. `BookId` and `CustomerId` follows the convention (TableName+Id) and it is good enough. Also with the current entity class definition the `Customer_CustomerId` will be a nullabe column in the Book table. So you can still save a record without CustomerId. Verified it in SQL server and EF 6. I Assume it works the same way in mysql – Shyju Oct 21 '17 at 00:35
  • That was also my understanding, but I tend to add the Key attribute just because I sometimes like to specify multiple columns in my primary key, and I've generally found it helps me realize the relational model behind the code easier. – Ratatoskr Oct 23 '17 at 14:08