实体框架0..1到0关系

时间:2011-05-12 15:14:48

标签: c# entity-framework foreign-keys

class First
{
    [Key]
    public int Id { get; set; }
}

class Second
{
    [Key]
    public int Id { get; set; }

    public int? First_Id { get; set; }

    [ForeignKey("First_Id")]
    public First First { get; set; }
}

public class SecondMapping : EntityTypeConfiguration<Second>
{
    public SecondMapping () 
        : base()
    {
        this.HasOptional(s => s.First)
            .With ... ???
    }
}

第二个可能会引用First。但是First从来没有提到Second。是否可以将此映射应用于Entity Framework 4.1?

修改 以前,这是我的解决方案:

this.HasOptional(s => s.First)
    .WithOptionalDependent()
    .WillCascadeOnDelete(false);

第二个可以包含First的一个实例(取决于某种Usage-Attribute)。首先不包含Second的任何实例。

2 个答案:

答案 0 :(得分:10)

只有当外键也是从属实体的主键时,才能实现一对一关系。所以正确的映射是:

class First
{
    [Key]
    public int Id { get; set; }
}

class Second
{
    [Key, ForeignKey("First")]
    public int Id { get; set; }
    public First First { get; set; }
}

原因是要在数据库中强制实施一对一关系,外键在Second实体中必须是唯一的。但实体框架不支持唯一键 - EF唯一的唯一值是主键。这是EF的限制。

Morteza Manavi's blog上介绍了解决方法。解决方法基于将关联映射为一对多,并通过在自定义数据库初始化程序中引入唯一约束来强制执行数据库中的唯一性。

答案 1 :(得分:0)

如果您正在尝试实现一对一关系,那么最多只有一个Second实体与First实体关联,并且没有反向属性尝试以下内容:

class First
{
    [Key]
    public Guid FirstId { get; set; }
}

class Second
{
    [Key]
    public Guid FirstId { get; set; }
    public First First { get; set; }
}

class SecondMapping : EntityTypeConfiguration<Second>
{
    public SecondMapping()
    {
        this.HasRequired(s => s.First);
    }
}

但是,您可以使用单独的First_id列来执行此类关联,但是您可以有效地创建1对N关系。它可以通过UNIQUE约束“强制”为1对1,但由于EF的限制,你将无法创建反向属性(如Ladislav所述):

class SecondMapping : EntityTypeConfiguration<Second>
{
    public SecondMapping()
    {
        this.HasRequired(s => s.First).WithMany().HasForeignKey("First_id");
    }
}