同一实体的外键,一个是必需的,另一个是可选的
Foreign keys to same Entity with one required and another optional
我正在尝试如下创建两个实体并使用 Fluent API 向它们添加引用约束。
它的设计是为了强制执行必需的主要联系人和可选的次要联系人,并增加了主要和次要联系人可能指的是 ContactInfo 实体中的两个不同联系人的要求。
public class Employee
{
public int EmployeeId { get; set; }
public int PrimaryContactId { get; set; }
public int SecondaryContactId { get; set; }
public virtual ContactInfo PrimaryContact { get; set; }
public virtual ContactInfo SecondaryContact { get; set; }
}
public class ContactInfo
{
public int ContactId { get; set; }
public string PhoneNumer { get; set; }
public string Email { get; set; }
}
public class EmployeeConfiguration : EntityTypeConfiguration<Employee>
{
public EmployeeConfiguration ()
{
var employeeEntity = this;
employeeEntity.HasKey(e => e.EmployeeId).ToTable("Employees");
employeeEntity.Property(e => e.EmployeeId).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);
employeeEntity.HasRequired(e => e.PrimaryContact).WithMany().HasForeignKey(e => e.PrimaryContactId).WillCascadeOnDelete(true);
employeeEntity.HasRequired(e => e.SecondaryContact ).WithMany().HasForeignKey(e => e.SecondaryContact Id).WillCascadeOnDelete(false);
}
}
它似乎按预期创建了所需的约束,但是当我尝试添加一个将 SecondaryContact 设置为 null 的员工时,为这个新员工创建的行将 SecondaryContactId 设置为与 PrimaryContactId 相同,这不是我的意图。
我一开始就无法理解设计是否正确,或者需要调整配置才能获得正确的结果。
您可以添加外键注释,如果您希望键为空,也可以将键设置为可为空。
public class Employee
{
public int EmployeeId { get; set; }
public int? PrimaryContactId { get; set; }
public int? SecondaryContactId { get; set; }
[ForeignKey("PrimaryContactId")]
public virtual ContactInfo PrimaryContact { get; set; }
[ForeignKey("SecondaryContactId")]
public virtual ContactInfo SecondaryContact { get; set; }
}
将辅助联系人 ID 设置为可为 null 的类型。
public int? SecondaryContactId { get; set; }
您似乎将这两个联系人都设置为您的员工对象需要。
如果你想要 SecondaryContract
可选更改:
employeeEntity
.HasRequired(e => e.SecondaryContact)
.WithMany()
.HasForeignKey(e => e.SecondaryContactId)
.WillCascadeOnDelete(false);
至
employeeEntity
.HasOptional(e => e.SecondaryContact)
.WithMany()
.HasForeignKey(e => e.SecondaryContactId)
.WillCascadeOnDelete(false);
另外更改:
public int SecondaryContactId { get; set; }
到
public int? SecondaryContactId { get; set; }
因为您的 SecondaryContactId 是可选的。
我正在尝试如下创建两个实体并使用 Fluent API 向它们添加引用约束。
它的设计是为了强制执行必需的主要联系人和可选的次要联系人,并增加了主要和次要联系人可能指的是 ContactInfo 实体中的两个不同联系人的要求。
public class Employee
{
public int EmployeeId { get; set; }
public int PrimaryContactId { get; set; }
public int SecondaryContactId { get; set; }
public virtual ContactInfo PrimaryContact { get; set; }
public virtual ContactInfo SecondaryContact { get; set; }
}
public class ContactInfo
{
public int ContactId { get; set; }
public string PhoneNumer { get; set; }
public string Email { get; set; }
}
public class EmployeeConfiguration : EntityTypeConfiguration<Employee>
{
public EmployeeConfiguration ()
{
var employeeEntity = this;
employeeEntity.HasKey(e => e.EmployeeId).ToTable("Employees");
employeeEntity.Property(e => e.EmployeeId).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);
employeeEntity.HasRequired(e => e.PrimaryContact).WithMany().HasForeignKey(e => e.PrimaryContactId).WillCascadeOnDelete(true);
employeeEntity.HasRequired(e => e.SecondaryContact ).WithMany().HasForeignKey(e => e.SecondaryContact Id).WillCascadeOnDelete(false);
}
}
它似乎按预期创建了所需的约束,但是当我尝试添加一个将 SecondaryContact 设置为 null 的员工时,为这个新员工创建的行将 SecondaryContactId 设置为与 PrimaryContactId 相同,这不是我的意图。
我一开始就无法理解设计是否正确,或者需要调整配置才能获得正确的结果。
您可以添加外键注释,如果您希望键为空,也可以将键设置为可为空。
public class Employee
{
public int EmployeeId { get; set; }
public int? PrimaryContactId { get; set; }
public int? SecondaryContactId { get; set; }
[ForeignKey("PrimaryContactId")]
public virtual ContactInfo PrimaryContact { get; set; }
[ForeignKey("SecondaryContactId")]
public virtual ContactInfo SecondaryContact { get; set; }
}
将辅助联系人 ID 设置为可为 null 的类型。
public int? SecondaryContactId { get; set; }
您似乎将这两个联系人都设置为您的员工对象需要。
如果你想要 SecondaryContract
可选更改:
employeeEntity
.HasRequired(e => e.SecondaryContact)
.WithMany()
.HasForeignKey(e => e.SecondaryContactId)
.WillCascadeOnDelete(false);
至
employeeEntity
.HasOptional(e => e.SecondaryContact)
.WithMany()
.HasForeignKey(e => e.SecondaryContactId)
.WillCascadeOnDelete(false);
另外更改:
public int SecondaryContactId { get; set; }
到
public int? SecondaryContactId { get; set; }
因为您的 SecondaryContactId 是可选的。