与可空外键的一对一关系

时间:2016-11-19 19:52:53

标签: c# entity-framework one-to-one

我想在EF中创建一对一关系,其中外键可以为null(因此,它可以被称为0..1到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);

但它在表ProductInstance中生成了两列:

  • Sale_id - 外键
  • SaleId

这是生成的迁移代码:

 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作为外键?

2 个答案:

答案 0 :(得分:5)

一对一或一对一的关系:

当一个表的主键变为PK&amp;时,发生一对一或一的关系。 FK在关系数据库(如SQL Server)中的另一个表中。

数据注释一对一或一,如下所示:

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

使用Fluent API进行一对一或零,如下所示:

ProductInstance

在上述情况下,可以在没有Sale的情况下保存Sale,但如果没有ProductInstance实体,则无法保存ProductInstance实体。 在上述情况下保持最小值,A Sale不能有多个ProductInstance

一对一的关系:

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

数据注释一对一如下:

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

Fluent API一对一,如下所示:

...
SidePanelButtonL1:
    title: 'Button1'
    on_press: root.dispatch('on_press')
    on_release: root.on_button1(self)


...
 def on_button1(self, bt1):
    Logger.debug('SidePanel: on_button1 %s' % bt1)
    pass

答案 1 :(得分:5)

EF不支持one-to-one关联显式FK属性 - 没有HasForeignKey流畅的API,如果您尝试使用ForeignKey数据注释解决它,您将获得迁移期间的多重性异常。

唯一的解决方案是删除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"));