0
votes

As I'm trying to get my head around with Entity Framework code-first and how to set relationships between entities. I encountered an issue when I was trying to insert (seed) some data into my database. I'm trying to insert a product object inside the buys (order) object. That product property in buys is virtual to state that it is a navigation property. Is there a different way of approaching what I wanted to achieve?

I run Add-Migration initial and I get an error:

The seed entity for entity type 'Buys' cannot be added because it has the navigation 'Customer' set. To seed relationships you need to add the related entity seed to 'Customer' and specify the foreign key values {'customerID'}. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the involved property values

Below is the seeding method which runs in the data context class.

private void SeedDatabase(ModelBuilder builder)
{
        // Construct Data
        var productType = new ProductType()
        {
            typeName = "Operating System"
        };

        var product = new Product()
        {
            typeID = productType.typeID,
            productName = "Windows",
            productVersion = "10 Home",
            productDescription = "This version of windows is the Home 10 edition",
            keyPrice = 10,
            license = "ASDEW-2342-SDE34-FGR35",
            ProductType = productType
        };

        var customer = new Customer()
        {
            customerEmail = "[email protected]",
            customerFullname = "John Derek"
        };

        var transaction = new Transaction()
        {
            paid = true,
            transactionAmount = 10
        };

        var order = new Buys()
        {
            customerID = customer.customerID,
            TransactionID = transaction.transcationID,
            quantity = 1,
            Date = new DateTime().Date,
            Transaction = transaction,
            Customer = customer,
            Product = product,
            productID = product.productID
        };

        transaction.Buy = order;
        System.Collections.Generic.List<Buys> orders = new System.Collections.Generic.List<Buys>() { order };
        product.customerBuys = orders;

        builder.Entity<ProductType>()
            .HasData(productType);

        builder.Entity<Product>()
           .HasData(product);

        builder.Entity<Customer>()
           .HasData(customer);

        builder.Entity<Transaction>()
           .HasData(transaction);

        builder.Entity<Buys>()
           .HasData(orders);
    }

And here are the 2 models that is mentioning about.

public class Customer
{
    public Customer()
    {
        customerID = Guid.NewGuid().ToString();
    }

    [Key]
    public string customerID { get; set; }
    public string customerFullname { get; set; }
    public string customerEmail { get; set; }
    public virtual ICollection<Buys> customerBuys { get; set; }
}

// This is a join table between product and customer.
// Product can have many customers
// One customer can purchase many products
public class Buys
{
    public Buys()
    {
        buyID = Guid.NewGuid().ToString();
    }

    [Key]
    public string buyID { get; set; }
    public string productID { get; set; }
    public virtual Product Product { get; set; }
    public string customerID { get; set; }
    public virtual Customer Customer { get; set; }
    public int quantity { get; set; }
    public DateTime Date { get; set; }
    public string TransactionID { get; set; }
    public virtual Transaction Transaction { get; set; }
}
1

1 Answers

0
votes

The Id fields are strings and you are not populating them anywhere. Try seeding those IDs before passing the object to HasData().

Example:

var productType = new ProductType()
{
    Id = Guid.NewGuid().ToString(), //If they are supposed to be GUIDs
    typeName = "Operating System"
};