繁体   English   中英

代码优先的可选一对一关系

[英]Code First Optional One-To-One Relationship

针对其中我有两个表(客户和用户)的情况编写模型。 每个用户记录都可能有一个可选的相关客户记录,反之亦然,但都不是必须的。 我发现FK Associations不是我所需要的,但Independent Associations是我所需要的。 但是我只是找到一种使它起作用的方法,我不断收到“无法确定主体端...必须使用关系流利的API或数据注释显式配置此关联的主体端”。 例外。

我的模型非常简单:

public class User
{
    [Key]
    public int          Id              { get; set; }
    [StringLength(20)]
    public string       CustomerId      { get; set; }
    public string       Password        { get; set; }
    public bool         Locked          { get; set; }

    //[ForeignKey("CustomerId")]
    public virtual Customer Customer    { get; set; }
}

public class Customer
{
    [Key]
    [Column("Id", TypeName = "nvarchar")]
    [StringLength(20)]
    public string       Id              { get; set; }   //  nvarchar    20
    [Required]
    public string       GivenName       { get; set; }   //  nvarchar    100
    [Required]
    public string       Surname         { get; set; }   //  nvarchar    100

    //[InverseProperty("Customer")]
    public virtual User User            { get; set; }
}

我试图添加ForeignKeyAttribute和InversePropertyAttribute,它们目前已被注释掉,但它们都没有帮助。 如果可能的话,我宁愿使用数据注释而不是流畅的API。

一对一关系中,一端必须是主体 ,第二端必须是从属关系 主体端是将首先插入的端,并且可以存在而无需从属端。 从属端是必须在主体后插入的一端,因为它具有主体的外键。 在配置一对一关系时,实体框架要求从属的主键也应为外键。通过在依赖类上使用ForeignKey批注来标识它包含外键,最容易解决此问题。 在您的情况下, Customer可能是从属,并且其键Customer.UserId也应该是外键。 但是两个键必须使用相同的类型声明:

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

   public virtual Customer Customer { get; set; }
}

public class Customer
{
   [Key, ForeignKey("User")]
   public int  UserId { get; set; }

   public virtual User User{ get; set; } 
}

我不知道如何使用数据注释解决问题,但是如果您想使用Fluent Api,我认为该关系的配置应如下所示:

 modelBuilder.Entity<User>().HasOptional(u => u.Customer).WithOptionalPrincipal(c => c.User);

更新

我了解您的情况,但是如果您在模型中显示的列相同,则我认为您应该在数据库中映射一对多关系,而不是一对一。 尝试通过以下方式映射您的关系:

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

    public string Password { get; set; }
    public bool Locked { get; set; }

    public string CustomerId { get; set; }

    [ForeignKey("CustomerId")]
    public virtual Customer Customer { get; set; }
}

public class Customer
{
    [Key]
    [Column("Id", TypeName = "nvarchar")]
    [StringLength(20)]
    public string Id { get; set; }   //  nvarchar    20
    [Required]
    public string GivenName { get; set; }   //  nvarchar    100
    [Required]
    public string Surname { get; set; }   //  nvarchar    100

    public virtual  ICollection<User> Users { get; set; }
}

请记住,使用与数据库中相同的列名映射属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM