ef core 2 - 在 table 'Y' 上引入 FOREIGN KEY 约束 'X' 可能会导致循环或多个级联路径
ef core 2 - Introducing FOREIGN KEY constraint 'X' on table 'Y' may cause cycles or multiple cascade paths
我知道,我知道,已经存在很多这样的问题,但我没有找到如何在我的场景中解决这个问题。
我有一个客户和一个卖家,一个客户没有必要卖家,但所有卖家都是客户。
在我的订单中,我有一个客户和一个卖家,但是seller 已经有一个 custumer 他
这是我的客户实体
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; }
[...]
}
我的卖家实体
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; }
}
我的订单实体
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
[...]
}
我的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;
}
}
我已经添加了迁移,但是当我设置 'update-database' 时,我收到此错误消息:
在 table 'Order' 上引入 FOREIGN KEY 约束 'FK_Order_Seller_SellerId' 可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。
无法创建约束或索引。查看以前的错误。
这是一个 .netcore2.0 项目,我使用的是 ef-core 2
解决方案
我在 Cutomer 中添加了一个卖家并将其映射到只有卖家有客户
cfg.HasOne(x => x.Customer).WithOne(y => y.Seller).HasForeignKey<Customer>(z => z.SellerId);
我的卖家地图
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;
}
}
我的客户地图
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;
}
}
我的卖家实体
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; }
}
}
我的客户实体
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
我知道,我知道,已经存在很多这样的问题,但我没有找到如何在我的场景中解决这个问题。
我有一个客户和一个卖家,一个客户没有必要卖家,但所有卖家都是客户。
在我的订单中,我有一个客户和一个卖家,但是seller 已经有一个 custumer 他
这是我的客户实体
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; }
[...]
}
我的卖家实体
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; }
}
我的订单实体
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
[...]
}
我的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;
}
}
我已经添加了迁移,但是当我设置 'update-database' 时,我收到此错误消息:
在 table 'Order' 上引入 FOREIGN KEY 约束 'FK_Order_Seller_SellerId' 可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。
无法创建约束或索引。查看以前的错误。
这是一个 .netcore2.0 项目,我使用的是 ef-core 2
解决方案
我在 Cutomer 中添加了一个卖家并将其映射到只有卖家有客户
cfg.HasOne(x => x.Customer).WithOne(y => y.Seller).HasForeignKey<Customer>(z => z.SellerId);
我的卖家地图
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;
}
}
我的客户地图
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;
}
}
我的卖家实体
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; }
}
}
我的客户实体
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