2011-05-16 88 views
26

我想在EF Code First中映射现有数据库中的可选1对1关系。EF代码优先 - 1对1可选关系

简单模式:

User 
Username 
ContactID 

Contact 
ID 
Name 

显然的ContactID加入到Contact.ID。 ContactID字段为空,所以关系是可选的 - 0或1,从不多。

那么,如何在EF Code First中使用此现有模式指定此关系?

这里是我试过到目前为止:

public class User 
{ 
    [Key] 
    public string Username { get; set; } 
    public int? ContactID { get; set; } 

    [ForeignKey("ContactID")] 
    public virtual Contact Contact { get; set; } 
} 

public class Contact 
{ 
    [Key] 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual User User { get; set; } 
} 

modelBuilder.Entity<User>().HasOptional<Contact>(u=> u.Contact) 
    .WithOptionalDependent(c => c.User); 

我得到以下异常:

System.Data.Edm.EdmAssociationEnd: : Multiplicity is not valid in Role 
'User_Contact_Source' in relationship 'User_Contact'. Because the Dependent 
Role properties are not the key properties, the upper bound of the multiplicity 
of the Dependent Role must be *. 

回答

42

一个解决办法是;

public class User 
{ 
    [Key] 
    public string Username { get; set; } 

    public virtual Contact Contact { get; set; } 
} 

public class Contact 
{ 
    [Key] 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual User User { get; set; } 
} 

     modelBuilder.Entity<User>() 
      .HasOptional<Contact>(u => u.Contact) 
      .WithOptionalDependent(c => c.User).Map(p => p.MapKey("ContactID")); 

您只在POCO中设置了导航对象,而使用流利API将您的密钥映射到正确的列。

+0

这帮助我在尝试配置0:1到0:1时解决以下问题 - 此关联的主体端必须使用关系流利API或数据注释进行显式配置。 – 2015-03-02 12:24:04

+1

我建议您按照约定包含外键属性(https://msdn.microsoft.com/zh-cn/data/jj679962)。如果每当你创建实体之间的关系时,通过这个关键属性而不是实体属性来完成。我已经找到了这种方式,在对象状态管理器中获得某些异常(如重复键)的可能性较小,并且在更新出错时更有意义的异常。 – MIP1983 2015-03-02 16:07:57

+9

如何在'User'中使用'ContactId'字段?如果我使用上面的代码并在User中定义了一个'ContactId'字段,它会给我一个错误,说它是一个重复的属性。我怎么能告诉实体框架,用'MapKey'定义的列和用户定义的'ContactId'是相同的。 – 2015-05-19 08:12:55