c# - Code First 可选的一对一关系

标签 c# asp.net-mvc entity-framework ef-code-first data-annotations

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

我的模型非常简单:

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。

最佳答案

一对一关系中,一端必须是主体,而另一端必须是从属主端是第一个插入的端,并且可以在没有从属端的情况下存在。 从属端是必须插入到主体之后的端,因为它具有主体的外键。配置一对一关系时, Entity Framework 要求依赖类的主键也是外键。通过在依赖类上使用 ForeignKey 注释来标识该类,可以最轻松地解决此问题它包含外键。在您的情况下,Customer 可能是依赖项,其键 Customer.UserId 也应该是外键。但两个 Key 必须使用相同的类型声明:

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; }
}

请记住将您的属性映射为与数据库中相同的列名称。

关于c# - Code First 可选的一对一关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28137341/

相关文章:

asp.net-mvc - WebApiController 和 HttpContext.Current.User 中的 User 是否不同?

entity-framework - Entity Framework 延迟加载

c# - 使用反射在谓词中引用类的属性

c# - WPF 应用程序中的复合 ViewModel

asp.net-mvc - 使用 Windows live ID 和 Azure AD 对 MVC 应用程序进行身份验证

javascript - 如何更改我搜索的文本颜色?

node.js - 如何在 Sequelize 中使用迁移?

c# - 如何向域实体注入(inject)服务以及如何持久化实体

c# - WPF - TabItem 内容在 tabitem.visibility=hidden 时仍然可见

c# - 如何使用 c# 在 asp.net 中的数据库中在我的网页中显示我的 docx 文件数据?