实体框架代码首先流畅的零到一个关系

时间:2015-08-10 14:10:14

标签: entity-framework entity-framework-6 ef-fluent-api

请不要将此标记为重复问题。我已经搜索了我可以在SO上找到的所有其他相关帖子,尝试过提出并接受的解决方案 - 这些都没有对我有用。

我的数据模型是ApplicationUser可能是也可能不是驱动程序,驱动程序必须是ApplicationUser。 ApplicationUser是Principal,Dri​​ver是Dependent。

public class ApplicationUser
{
  public int Id { get; set; }
  public virtual Driver Driver { get; set; }
}

 public class Driver
 {
   public int Id{ get; set; }
   public virtual ApplicationUser User { get; set; }
}

在物理域中,除了ID之外,不应该有其他键(PK或FK)。

我认为EF模型将驱动程序的Id属性设置为PK和FK,所以在逻辑上,ApplicationUser必须首先存在,其PK也可以用作驱动程序的PK。

我在SO帖子上尝试了所有流畅的建模变体,我大多得到的错误大致上说“[你需要将一方标记为校长]”。

当我在Driver类中将[Required]属性放在ApplicationUser属性之上时,这是有效的。

我似乎无法找到合适的流利映射语句来模仿它。

最初会想到这应该做到,但事实并非如此:

modelBuilder.Entity<Driver>()
        .HasRequired(e => e.User)
        .WithOptional(e=> e.Driver);

我认为HasRequired(e =&gt; e.User)对于[Required]属性来说是一回事,但我猜不是......

我想知道这是否可能是EF 6.1.3中的错误。

非常感谢任何建议。

由于

2 个答案:

答案 0 :(得分:1)

这些映射应该有效

public class ApplicationUserMap : EntityTypeConfiguration<ApplicationUser>
{
    public ApplicationUserMap()
    {
        this.HasOptional(x => x.Driver)
            .WithOptionalPrincipal()
            .Map(x => x.MapKey("Id"));
    }
}

public class DriverMap : EntityTypeConfiguration<Driver>
{
    public DriverMap()
    {
        this.HasOptional(x => x.ApplicationUser)
            .WithOptionalPrincipal()
            .Map(x => x.MapKey("Id"));
    }
}

从评论中更新

正如您在问题中提到的,您有一个原则和依赖实体。问题是EF不知道哪个是一对一或一对一关系,因此您需要使用数据注释。为此,请将您的Driver类更改为:

public class Driver
{
   [Key, ForeignKey("ApplicationUser")]
   public int Id{ get; set; }
   public virtual ApplicationUser User { get; set; }
}

由于您没有使用EF命名惯例,我建议您在尝试此操作之前将其ID的名称更改为ApplicationUserIDDriverID,正如Nick L在答案中提到的那样如果你还没有这样做的话。

我不完全确定,但如果可行的话,您可能不需要使用Fluent映射。

答案 1 :(得分:0)

嗯,我认为不一样。 IInterface主要用于应用switch映射。您可以在配置中尝试HasRequired

0..1-N

更新:另一个问题是你没有按照惯例IsRequired在你的课程中给出ID,以便EF自动映射它。您应该有Property(e => e.User).IsRequired(); ClassNameID,否则您必须在主体上设置您的流畅API配置的映射,正如sleaver建议的那样。