c# - EF Core Net 5 - 代码优先 - 与同一实体的多个关系
问题描述
我正在尝试在两个实体之间设置多个关系,如下所示:
一家公司有多个地址。
一家公司有一个默认地址。
一家公司有一个默认帐单地址。
一家公司有一个默认送货地址。
public abstract class BaseAddress : AbstractValidatableEntity
{
public AddressType Type { get; set; }
public AddressStatus Status { get; set; }
public Country Country { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public string Address4 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
}
public class CompanyAddress : BaseAddress
{
public Guid CompanyId { get; set; }
public Company Company { get; set; }
}
public class Company : AbstractValidatableEntity
{
public string Name { get; set; }
public List<User> Users { get; set; }
public Guid OwnerId { get; set; }
public User Owner { get; set; }
public List<CompanyAddress> Addresses { get; set; }
public CompanyAddress DefaultAddress { get; set; }
public CompanyAddress DefaultBillingAddress { get; set; }
public CompanyAddress DefaultDeliveryAddress { get; set; }
}
public class CompanyConfiguration : AbstractEntityConfiguration<Company>
{
public override void Configure(EntityTypeBuilder<Company> builder)
{
base.Configure(builder);
// Table name
builder
.ToTable("Companies");
// Columns
builder
.Property(s => s.Name)
.IsRequired(true)
.HasMaxLength(255);
// Relationships
builder
.HasMany(s => s.Users)
.WithOne(u => u.Company)
.HasForeignKey(u => u.CompanyId)
.IsRequired(false)
.HasConstraintName("FK_COMPANY_USERS");
builder
.HasMany(s => s.Addresses)
.WithOne(a => a.Company)
.HasForeignKey(a => a.CompanyId)
.IsRequired()
.HasConstraintName("FK_COMPANY_ADDRESSES")
.OnDelete(DeleteBehavior.Cascade);
builder
.HasOne(s => s.DefaultAddress)
.WithOne()
.HasForeignKey<CompanyAddress>(da => da.CompanyId)
.IsRequired(false)
.HasConstraintName("FK_COMPANY_DEFAULT_ADDRESS")
.OnDelete(DeleteBehavior.Restrict);
builder
.HasOne(s => s.DefaultBillingAddress)
.WithOne()
.HasForeignKey<CompanyAddress>(da => da.CompanyId)
.IsRequired(false)
.HasConstraintName("FK_COMPANY_DEFAULT_BILLING_ADDRESS")
.OnDelete(DeleteBehavior.Restrict);
builder
.HasOne(s => s.DefaultDeliveryAddress)
.WithOne()
.HasForeignKey<CompanyAddress>(da => da.CompanyId)
.HasConstraintName("FK_COMPANY_DEFAULT_DELIVERY_ADDRESS");
// Indexes
builder
.HasIndex(s => s.Name)
.HasDatabaseName("IX_COMPANY_NAME");
}
}
但是在创建数据库时出现以下错误:
System.InvalidOperationException:'无法确定由'List'类型的导航'Company.Addresses'表示的关系。手动配置关系,或使用“[NotMapped]”属性或使用“OnModelCreating”中的“EntityTypeBuilder.Ignore”忽略此属性。
请注意,我试图在同一个表中实现 1 个多对一关系和 3 个一对一关系,这与我在此处搜索的所有其他问题不同。
我读过多个类似的问题,但它们都有以下情况:
一家公司有多个地址。
一家公司有一个默认地址。
如果我在我的代码中删除第二个和第三个一对一关系,它就可以完美地工作。我不确定在代码方面该怎么做。
我确实知道我可以在数据库方面做到这一点。拥有一个 CompanyAdresses 表并在 Company 表上具有以下属性:DefaultAddressId、DefaultBillingAddressId、DefaultDeliveryAddressId。
在此先感谢大家。
解决方案
对于 Company 和 Address 之间具有不同语义的每个关系,您应该有一个 ForeignKey。例如:
public class Company : AbstractValidatableEntity
{
public string Name { get; set; }
public List<User> Users { get; set; }
public Guid OwnerId { get; set; }
public User Owner { get; set; }
public List<CompanyAddress> Addresses { get; set; }
public CompanyAddress DefaultAddress { get; set; }
public CompanyAddress DefaultBillingAddress { get; set; }
public CompanyAddress DefaultDeliveryAddress { get; set; }
public Guid DefaultAddressId { get; set; }
public Guid DefaultBillingAddressId { get; set; }
public Guid DefaultDeliveryAddressId { get; set; }
}
然后,使用自己的 FK 配置每个关系。
...
builder
.HasOne(s => s.DefaultAddress)
.WithOne()
.HasForeignKey<Company>(da => da.DefaultAddressId)
.IsRequired(false)
.HasConstraintName("FK_COMPANY_DEFAULT_ADDRESS")
.OnDelete(DeleteBehavior.Restrict);
builder
.HasOne(s => s.DefaultBillingAddress)
.WithOne()
.HasForeignKey<Company>(da => da.DefaultBillingAddressId)
.IsRequired(false)
.HasConstraintName("FK_COMPANY_DEFAULT_BILLING_ADDRESS")
.OnDelete(DeleteBehavior.Restrict);
builder
.HasOne(s => s.DefaultDeliveryAddress)
.WithOne()
.HasForeignKey<Company>(da => da.DefaultDeliveryAddressId)
.HasConstraintName("FK_COMPANY_DEFAULT_DELIVERY_ADDRESS");
...
推荐阅读
- linux - zsh 中“git stash drop”的别名
- awesome-wm - 将客户端窗口垂直最大化到屏幕的左半边
- google-tag-manager - 任何人都可以使用基于函数的 id 帮助实现 Nuxt.js Google Tag Manager
- c# - 使用 Microsoft Graph 将 C# Asp.Net Core 中的文件上传到 Sharepoint/OneDrive,无需用户交互
- c# - CP Solver 性能问题
- pandas - pandas - 获取重复行的计数(跨多列匹配)
- powershell - 如何根据这些条件转换字符串?(无垃圾邮件到真正的电子邮件)
- python - 无法在 Python 中导入我自己的依赖项
- performance - 在高负载应用程序中使用装饰器是个好主意吗?
- python - 如何使用 CNN-LSTM 对不同长度的视频进行分类?