与可为空的外键的一对一关系

One-To-One relationship with nullable foreign keys

我想在 EF 中创建外键可以为空的一对一关系(因此,它可以称为 0..1-to-0..1)

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

    public int SaleId { get; set; }
    public Sale Sale { get; set; }
}


public class Sale
{
    public int Id { get; set; }
    public ProductInstance ProductInstance { get; set; }
}

FluentAPI配置:

modelBuilder.Entity<Sale>()
   .HasOptional(x => x.ProductInstance)
   .WithOptionalPrincipal(x => x.Sale);

但是它在 table ProductInstance:

中生成了两列

这里是生成的迁移代码:

 CreateTable(
            "dbo.ProductInstances",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    SaleId = c.Int(nullable: false),
                    Sale_Id = c.Int(),
                })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.Sales", t => t.Sale_Id)
            .Index(t => t.Sale_Id);

我怎样才能只得到一列 SaleId 作为外键?

一对零或一的关系:

当一个 table 的主键在关系数据库(例如 SQL 中成为另一个 table 的主键和外键时,就会发生一对零或一的关系服务器。

一对一与数据标注如下:

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

    public virtual Sale Sale { get; set; }
}


public class Sale
{
    [Key]
    [ForeignKey("ProductInstance")]
    public int ProductInstanceId { get; set; }

   ///write here other properties

    public virtual ProductInstance ProductInstance { get; set; }
}

一对一与FluentAPI如下:

modelBuilder.Entity<ProductInstance>()
                .HasOptional(s => s.Sale)
                .WithRequired(ad => ad.ProductInstance);

在上述情况下,ProductInstance 可以在没有 Sale 的情况下保存,但 Sale 实体不能在没有 ProductInstance 实体的情况下保存。 在上面的例子中保持min,一个ProductInstance不能超过一个Sale.

一对一关系:

我们无法在需要两端的实体之间配置一对一关系,这意味着 ProductInstance 实体对象必须包含 Sale 实体对象和 Sale 实体必须包含 ProductInstance 实体对象才能保存它。在 MS SQL 服务器中,一对一关系在技术上是不可能的。但是我们可以配置实体之间的一对一关系,其中两端或至少一端是可选的,如下所示:

一对一与数据标注如下:

public class Department
{
    [Key]
    public int DepartmentId { get; set; }

    ForeignKey("Person")]
    public int PersonId { get; set; }

    public virtual Person Person { get; set; }
}


public class Person
{
    [Key]
    public int PersonId { get; set; }

    [ForeignKey("Department")]
    public int? DepartmentId { get; set; }


    public virtual Department Department { get; set; }
}

与Fluent一对一API如下:

modelBuilder.Entity<Person>()
                .HasOptional(pi => pi.Department)
                .WithMany()
                .HasForeignKey(s => s.DepartmentId);

EF 不支持 one-to-one 与显式 FK 的关联 属性 - 没有 HasForeignKey 流畅的 API,如果您尝试使用 [=14= 解决它] 数据注释,你会在迁移过程中得到多重性异常。

唯一的解决方案是删除 ProductInstance.SaleId 属性,最终模型为:

public class ProductInstance
{
    public int Id { get; set; }
    public Sale Sale { get; set; }
}

public class Sale
{
    public int Id { get; set; }
    public ProductInstance ProductInstance { get; set; }
}

和配置:

modelBuilder.Entity<Sale>()
   .HasOptional(x => x.ProductInstance)
   .WithOptionalPrincipal(x => x.Sale)
   .Map(a => a.MapKey("SaleId"));