具有一个所需的同一个实体的外键和另一个可选的外键

时间:2016-03-09 13:48:26

标签: entity-framework ef-fluent-api

我正在尝试创建两个实体,如下所示,并使用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的员工添加时,为此新Employee创建的行的SecondaryContactId设置为与PrimaryContactId相同,这不是我的意图。

我无法首先了解设计是否正确,或者需要调整配置以获得正确的结果。

3 个答案:

答案 0 :(得分:1)

您可以添加外键注释,并且如果您希望其为空,也可以将键设置为可为空。

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; }
}

答案 1 :(得分:1)

使辅助联系人ID成为可以为空的类型。

public int? SecondaryContactId { get; set; }

答案 2 :(得分:1)

您似乎设置了员工对象所需的两个联系人。 如果您想进行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是可选的。