Entity Framework - 如何对模型属性应用约束?

Entity Framework - How to apply constraint to model properties?

我正在使用 Entity Framework 6.1.3 并且有如下所示的两个模型。但是,当我 运行 迁移时,出现以下错误:

Unable to determine the principal end of an association between the types 'Example.Models.GiftVoucher' and 'Example.Models.Payment'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

我搜索了一下,找到了this question。解决方案之一是使用 Required 属性。

但是,我不知道如何在 Entity Framework 中执行以下操作:

支付模式

public class Payment { 

    public int Id { get; set; }

    [Required]
    public DateTime DateTime { get; set; }

    public double Amount { get; set; }

    [Required]
    public int GiftVoucherId { get; set; }
    public GiftVoucher GiftVoucher { get; set; }

}

礼券模型

public class GiftVoucher
{
    public int Id { get; set; }

    public double Amount { get; set; }

    [Required]
    public int PaymentId { get; set; }
    public Payment Payment { get; set; }

}

我不太倾向于使用一对一关系...除非我想垂直分区性能需求或不断 OCD 需要分离关注点。

*注意:在SQL 服务器中,一对一关系在技术上是不可能的。它将始终是 一对零或一。 EF 在不在数据库中的实体上形成一对一关系。*

但是,文档是您的朋友

Configuring a Relationship Where Both Ends Are Required (One-to-One)

In most cases the Entity Framework can infer which type is the dependent and which is the principal in a relationship. However, when both ends of the relationship are required or both sides are optional the Entity Framework cannot identify the dependent and principal. When both ends of the relationship are required, use WithRequiredPrincipal or WithRequiredDependent after the HasRequired method. ...

鉴于以下

public class GiftVoucher
{
    // your primary key
    public int GiftVoucherId { get; set; }
    public virtual Payment Payment { get; set; }

    // other properties
    public double Amount { get; set; }
}

public class Payment 
{ 
    // We need to share the same key
    public int GiftVoucherId { get; set; }
    public virtual GiftVoucher GiftVoucher { get; set; }

    // other properties
    public DateTime DateTime { get; set; }
    public double Amount { get; set; }
}

我们可以这样流利API

// Configure the primary key for the OfficeAssignment 
modelBuilder.Entity<Payment>() 
    .HasKey(t => t.GiftVoucherId); 

// we are essentially making GiftVoucher the principle in the DB
modelBuilder.Entity<GiftVoucher>() 
    .HasRequired(t => t.Payment) 
    .WithRequiredPrincipal(t => t.GiftVoucher);

所以基本上 HasRequired 需要 GiftVoucherWithRequiredPrincipal 需要 Payment.. 反过来,如果不满足上述条件,EF 将抛出