简体   繁体   English

具有可空外键的一对一关系

[英]One-To-One relationship with nullable foreign keys

I want to create One-To-One relationship in EF where Foreign Keys can be null (So, It can be called 0..1-to-0..1) 我想在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 configuration: FluentAPI配置:

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

But it's generate two columns in table ProductInstance : 但这会在表ProductInstance生成两列:

  • Sale_id - foreign key Sale_id外键
  • SaleId

Here is generated migration code: 这是生成的迁移代码:

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

How can I do to get only one column SaleId which will be Foreign key? 我怎样才能只获得将成为外键的一列SaleId

One-to-zero-or-one relationship: 一对零或一对关系:

A one-to-zero-or-one relationship happens when a primary key of one table becomes PK & FK in another table in a relational database such as SQL Server. 当一个表的主键在关系数据库(例如SQL Server)的另一个表中成为PK&FK时,就会发生一对零或一个关系。

One-to-zero-or-one with Data Annotation as follows: 带有数据注释的一对零或一对,如下所示:

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

One-to-zero-or-one with Fluent API as follows: 用Fluent API一对一或一如下:

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

In above case, a ProductInstance can be saved without Sale but the Sale entity cannot be saved without the ProductInstance entity. 在上述情况下,可以在没有Sale情况下保存ProductInstance但在没有ProductInstance实体的情况下不能保存Sale实体。 Keep in min in the above case, A ProductInstance cannot have more than one Sale . 在上述情况下,请注意,一个ProductInstance不能具有多个Sale

One-to-One relationship: 一对一关系:

We can not configure a one-to-One relationship between entities where both ends are required, meaning that the ProductInstance entity object must include the Sale entity object and the Sale entity must include the ProductInstance entity object in order to save it. 我们无法在需要两端的实体之间配置一对一关系,这意味着为了保存它, ProductInstance实体对象必须包括Sale实体对象,而Sale实体必须包括ProductInstance实体对象。 One-to-one relationships are technically not possible in MS SQL Server. 从技术上讲,MS SQL Server中不可能实现一对一的关系。 But we can configure one-to-One relationship between entities where both ends or at least one end is optional as follows: 但是我们可以配置实体之间的一对一关系,其中两端或至少一端是可选的,如下所示:

One-to--one with Data Annotation as follows: 一对一的数据注释如下:

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

One-to-one with Fluent API as follows: 与Fluent API一对一,如下所示:

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

EF does not support one-to-one associations with explicit FK property - there is no HasForeignKey fluent API and if you try to workaround it with ForeignKey data annotation, you'll get multiplicity exception during the migration. EF不支持具有显式FK属性one-to-one关联-没有HasForeignKey流利的API,如果尝试使用ForeignKey数据批注解决它,则在迁移期间会出现多重异常。

The only solution is to remove the ProductInstance.SaleId property, ending up with model: 唯一的解决方案是删除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; }
}

and configuration: 和配置:

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

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

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