I know, I know, already exist many questions like that, but I dont find how can I solve this problem in my scenario.
I have a customer and a have a seller, a customer not necessary is a seller, but all seller is a customer.
In my order I have a customer and a seller, but a seller already have a custumer inside him
It's my Customer Entity
public class Customer : BaseEntity
{
public Customer(Name name, DateTime? birthDay, Email email, string password, List<CreditDebitCard> creditDebitCards = null)
{
[...]
}
public Name Name { get; private set; }
public DateTime? BirthDay { get; private set; }
public Email Email { get; private set; }
public string Password { get; private set; }
public int? CreditDebitCardId { get; private set; }
public ICollection<CreditDebitCard> CreditDebitCards => _CreditDebitCards;
public IEnumerable<Order> Orders { get; private set; }
[...]
}
My Seller Entity
public class Seller : BaseEntity
{
public Seller(string schoolName, string cardIdPath, string identityNumber, int customerId)
{
[...]
}
public string SchoolName { get; private set; }
public string CardIdPath { get; private set; }
public string IdentityNumber { get; private set; }
public Customer Customer { get; private set; }
public int CustomerId { get; private set; }
public IEnumerable<Order> Orders { get; private set; }
}
My Order Entity
public class Order : BaseEntity
{
public Order(IList<OrderItem> orderItems, int customerId, int sellerId)
{
[...]
}
#region Fields
private IList<OrderItem> _orderItems;
#endregion
#region Properties
public int SellerId { get; private set; }
public Seller Seller { get; private set; }
public int CustomerId { get; private set; }
public Customer Customer { get; private set; }
public EOrderStatus Status { get; private set; }
public ICollection<OrderItem> OrderItems
{
get { return _orderItems; }
private set { _orderItems = new List<OrderItem>(value); }
}
public decimal Total => GetTotal();
#endregion
[...]
}
My OrderMap
public static class OrderMap
{
public static EntityTypeBuilder<Order> Map(this EntityTypeBuilder<Order> cfg)
{
cfg.ToTable("ORDER");
cfg.HasKey(x => x.Id);
cfg.Property(x => x.CreationDate).IsRequired();
cfg.Property(x => x.IsActive).IsRequired();
//cfg.Property(x => x.Discount).HasColumnType("money");
cfg.Property(x => x.Status).IsRequired();
cfg.HasMany(x => x.OrderItems);
cfg.HasOne(x => x.Customer);
cfg.HasOne(x => x.Seller).WithMany(b => b.Orders).OnDelete(DeleteBehavior.ClientSetNull);
return cfg;
}
}
I already add a migration, but when i will set 'update-database' I get this error message:
Introducing FOREIGN KEY constraint 'FK_Order_Seller_SellerId' on table 'Order' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint or index. See previous errors.
it's a .netcore2.0 project and i'm using the ef-core 2
Solution
I added a seller into Cutomer and mapped it to only the seller have a customer
cfg.HasOne(x => x.Customer).WithOne(y => y.Seller).HasForeignKey<Customer>(z => z.SellerId);
My Seller map
public static class SellerMap
{
public static EntityTypeBuilder<Seller> Map(this EntityTypeBuilder<Seller> cfg)
{
cfg.ToTable("SELLER");
cfg.HasKey(x => x.Id);
cfg.Property(x => x.CreationDate).IsRequired();
cfg.Property(x => x.IsActive).IsRequired();
cfg.HasOne(x => x.Customer).WithOne(y => y.Seller).HasForeignKey<Customer>(z => z.SellerId);
cfg.Property(x => x.CardIdPath).IsRequired();
cfg.Property(x => x.IdentityNumber);
cfg.Property(x => x.SchoolName);
return cfg;
}
}
MY Customer Map
public static class CustomerMap
{
public static EntityTypeBuilder<Customer> Map(this EntityTypeBuilder<Customer> cfg)
{
cfg.ToTable("CUSTOMER");
cfg.HasKey(x => x.Id);
cfg.Property(x => x.CreationDate).IsRequired();
cfg.Property(x => x.IsActive).IsRequired();
cfg.Property(x => x.BirthDay).IsRequired();
cfg.OwnsOne(x => x.Email);
cfg.OwnsOne(x => x.Name);
cfg.HasMany(x => x.CreditDebitCards).WithOne(y => y.Customer);
//cfg.HasOne(x => x.Seller).WithOne(y => y.Customer).IsRequired(false);
return cfg;
}
}
My Seller entity
public class Seller : BaseEntity
{
public Seller(string schoolName, string cardIdPath, string identityNumber, int customerId)
{
SchoolName = schoolName;
CardIdPath = cardIdPath;
IdentityNumber = identityNumber;
CustomerId = customerId;
}
public string SchoolName { get; private set; }
public string CardIdPath { get; private set; }
public string IdentityNumber { get; private set; }
public Customer Customer { get; private set; }
public int CustomerId { get; private set; }
public IEnumerable<Product> Products { get; private set; }
public int? ProductId { get; private set; }
public IEnumerable<Order> Orders { get; private set; }
}
}
My Customer entity
public class Customer : BaseEntity
{
public Customer(Name name, DateTime? birthDay, Email email, string password, List<CreditDebitCard> creditDebitCards = null)
{
CreationDate = DateTime.Now;
Name = name;
BirthDay = birthDay;
Email = email;
Password = password;
_CreditDebitCards = creditDebitCards ?? new List<CreditDebitCard>();
}
#region Fields
private IList<CreditDebitCard> _CreditDebitCards;
#endregion
#region Properties
public Name Name { get; private set; }
public DateTime? BirthDay { get; private set; }
public Email Email { get; private set; }
public string Password { get; private set; }
public int? CreditDebitCardId { get; private set; }
public ICollection<CreditDebitCard> CreditDebitCards => _CreditDebitCards;
public IEnumerable<Order> Orders { get; private set; }
public Seller Seller { get; private set; }
public int SellerId { get; private set; }
#endregion