sql-serverasp.net-coreasp.net-core-webapidatabase-relations

Unable to determine the relationship represented by navigation 'Customer.BoughtProducts' of type 'ICollection<Product>'


I have 3 models and a User class which defines the common properties for customer and seller so I won't attach it (I guess it would be useless info).

public class Seller : User
{
    public bool IsApproved { get; set; }

    public ICollection<Product> WaitingForShipping { get; set; }

    public ICollection<Product> ProductsOnSell { get; set; }
} 

public class Customer : User
{
    public bool IsSubscriber { get; set; }

    public ICollection<Product> WaitingForReceiving { get; set; }

    public ICollection<Product> BoughtProducts { get; set; }
}

public class Product
{
    [Key] public Guid Id { get; set; }

    public string Name { get; set; }

    public decimal Price { get; set; }

    public string Description { get; set; }

    public ProductCategory Category { get; set; }

    public int SellerId { get; set; }
    [ForeignKey("SellerId")] public Seller ProductSeller { get; set; }

    public int CustomerId { get; set; }

    [ForeignKey("CustomerId")] public Customer ProductCustomer { get; set; }

    public ICollection<Characteristic> ProductInfo { get; set; }

    public ICollection<Image> ImagesURLs { get; set; }

    public long Quantity { get; set; }

    public long AmountSold { get; set; }

    public byte Rating { get; set; }

    public bool InStock { get; set; }
}

And the last is the DbContext class

public class AppDbContext : DbContext
{
    public DbSet<Customer> Customers { get; set; }

    public DbSet<Seller> Sellers { get; set; }

    public DbSet<Product> Products { get; set; }

    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        
        // There were a lot of useless tries of configuring the relationships like
        // this
        // modelBuilder.Entity<Customer>().HasMany(prods => prods.BoughtProducts)
        // .WithOne(s => s.ProductSeller).HasForeignKey(i => i.SellerId);
        base.OnModelCreating(modelBuilder);
    }
}

When I use:

dotnet ef migrations add inital

into the terminal I get this:

Unable to determine the relationship represented by navigation'Customer.BoughtProducts' of type 'ICollection'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

I have no idea how to fix it.


Solution

  • I don't know your Customer's code. But I guess you maybe use ICollection<Product> for more than one. Take seller as an example.

    According to your Seller.cs, I add below code in Product,

            public Guid SellerId { get; set; }
            public Seller ProductSeller { get; set; }
    
            public Guid OnSellId { get; set; }
            public Seller OnSell { get; set; }
    

    And add .OnDelete(DeleteBehavior.Restrict); in Context

     protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                modelBuilder.Entity<Product>()
           .HasOne(p => p.ProductSeller)
           .WithMany(t => t.WaitingForShipping)
           .HasForeignKey(m => m.SellerId)
           .OnDelete(DeleteBehavior.Restrict);
    
                modelBuilder.Entity<Product>()
                    .HasOne(p => p.OnSell)
                    .WithMany(t => t.ProductsOnSell)
                    .HasForeignKey(m => m.OnSellId)
                    .OnDelete(DeleteBehavior.Restrict);
    
    
            }
    

    It works, My customer.cs is below.If your Customer.cs like seller, change code in Product and Context like me.

    public class Customer
        {
            public int CustomerId { get; set; }
            public string CustomerName { get; set; }
          
           
            public ICollection<Product> BoughtProducts { get; set; }
           
        }
    

    Update for Customer

    Add in Context:

    modelBuilder.Entity<Product>()
           .HasOne(p => p.ProductCustomer)
           .WithMany(t => t.WaitingForReceiving)
           .HasForeignKey(m => m.CustomerId)
           .OnDelete(DeleteBehavior.Restrict);
    
                modelBuilder.Entity<Product>()
                    .HasOne(p => p.BoughtCustomer)
                    .WithMany(t => t.BoughtProducts)
                    .HasForeignKey(m => m.BoughtId)
                    .OnDelete(DeleteBehavior.Restrict);
    

    Add in product:

           public Guid CustomerId { get; set; }
           public Customer ProductCustomer { get; set; }
            
            public Guid BoughtId { get; set; }
            public Customer BoughtCustomer { get; set; }