11

我想使用 EF Code First 在两个实体之间创建双向一对一关系。我对以下代码有疑问。你觉得我应该怎么做?

public class User
{
    public string ID { get; set; }
    public string LastName { get; set; }
    public string Password { get; set; }
    public string FirstName { get; set; }

    public int ProfileID { get; set; }
    public Profile Profile { get; set; }

}
public class Profile
{
    public int UserID { get; set; }
    public User User { get; set; }
    public int ProfileID { get; set; }
    public string ProfileName { get; set; }

    public DateTime CreateDate { get; set; }
    public DateTime LastUpdateDate { get; set; }

}

我想在两个实体中同时拥有 Navigation 属性和外键。

这给了我错误。我可以在 Fluent Mapping API 中做些什么来完成这项工作?

4

1 回答 1

18

用这个:

public class User
{
    public string ID { get; set; }
    public string LastName { get; set; }
    public string Password { get; set; }
    public string FirstName { get; set; }
    public Profile Profile { get; set; }
}

public class Profile
{
    [Key, ForeignKey("User")]
    public int ProfileID { get; set; }
    public string ProfileName { get; set; }
    public DateTime CreateDate { get; set; }
    public DateTime LastUpdateDate { get; set; }
    public User User { get; set; }
}

这是在 EF 中建立一对一关系的唯一有效方法 - 依赖实体的 PK 对主体实体也必须是 FK。EF 中没有双向的一对一关系,因为它不能在 EF 中工作。

人们有时克服这个问题的方法是两个一对多的关系,其中主体没有依赖实体的导航集合 + 数据库中手动定义的唯一键。这需要手动映射:

public class User
{
    public string ID { get; set; }
    public string LastName { get; set; }
    public string Password { get; set; }
    public string FirstName { get; set; }
    // one side MUST be nullable otherwise you have bidirectional constraint where each
    // entity demands other side to be inserted first = not possible
    public int? ProfileId { get; set; } 
    public Profile Profile { get; set; }
}

public class Profile
{
    public int ProfileID { get; set; }
    public string ProfileName { get; set; }
    public DateTime CreateDate { get; set; }
    public DateTime LastUpdateDate { get; set; }
    public int UserId { get; set; }
    public User User { get; set; }
}

在映射中,您将定义:

modelBuilder.Entity<User>
            .HasOptional(u => u.Profile)
            .WithMany()
            .HasForeignKey(u => u.ProfileId);
modelBuilder.Entity<Profile>
            .HasRequired(u => u.User)
            .WithMany()
            .HasForeignKey(u => u.UserId);

现在您必须在数据库中定义唯一键 - 如果您使用代码首先使用自定义数据库初始化r。请注意,双向一对一仍然是错误的概念,因为双方都需要唯一的 FK,其中 NULL 仍包含在唯一值中,因此一旦您插入User之前Profile,就不能再有其他User没有Profile. 这可能会导致可序列化的事务。

于 2011-06-08T08:56:54.793 回答