具有1:1关系的实体框架HasForeignKey错误

问题描述 投票:0回答:1

[建立一对多关系时,我可以做到这一点,并且有效:

EntityTypeBuilder<BrandOwner> brandOwner = X

brandOwner.HasMany(a => a.Brands).WithOne(b => b.Owner).HasForeignKey("OwnerId");

在1:1关系中,我可以使用此语法,并且它可以正常工作(观察常规的HasForeignKey)

person.HasOne(a => a.SinCard).WithOne(b => b.Owner).HasForeignKey<SocialInsuranceCard>(c => c.OwnerId);

但是这会导致错误:

person.HasOne(a => a.SinCard).WithOne(b => b.Owner).HasForeignKey("OwnerId");

错误是:InvalidOperationException:您正在配置'Person'和'SocialInsuranceCard'之间的关系,但已在'OwnerId'上指定了外键。必须在关系的一部分类型上定义外键。

示例类别:

public class BrandOwner
{
    public int Id { get; set; }
    public virtual List<Brand> Brands { get; set; }
}

public class Brand
{
    public int Id { get; set; }
    public int OwnerId { get; set; } // I'm aware of the "BrandOwnerId" convention
    public virtual BrandOwner Owner { get; set; }
}


pubic class Person
{
    public int Id { get; set; }
    public virtual SocialInsuranceCard SinCard { get; set; }
}

pubic class SocialInsuranceCard
{
    public int Id { get; set; }
    public int OwnerId; // I know I could get auto mapping by using "PersonId"
    public virtual Person Owner { get; set; }
}

为什么在1:1关系中使用非通用HasForeignKey会给出错误?

entity-framework asp.net-core-2.0
1个回答
0
投票

您拥有的结构不是一对一,而是一对多。通常将一对一设置为共享相同的ID:

public class Car
{
    public int CarId { get; set; }
    public virtual Seat seat { get; set; }
}

public class Seat
{
    public int CarId { get; set; } // PK and FK to Car
    public virtual Car car { get; set; }
}

这假设1辆汽车有1个座位。如果要确定诸如可以在多个座位上的汽车中的主要座椅之类的东西,则可能需要类似以下内容:

public class Car
{
    public int CarId { get; set; }
    public virtual ICollection<Seat> Seats { get; set; }
    public virtual Seat PrimarySeat { get; set; }
}

public class Seat
{
    public int SeatId { get; set; } // PK
    public int CarId { get; set; } // FK to Car 1-to-Many
    public virtual Car car { get; set; }
}

此关系需要在汽车上使用座位ID:

public class Car
{
    // ...
    public int PrimarySeatId { get; set; } // FK for Primary Seat
}

可能会进行设置,但是需要为所有汽车和座椅之间的关系进行显式映射,而不是按照惯例进行映射。 Car将明确需要知道如何解析其Seats集合(在Seat上使用CarId)并解析PrimarySeat实例。 (多对一)这不是一对一,特别是因为没有什么可以阻止多辆汽车将相同的SeatID指定为主要的。此外,也没有任何强制性规定PrimarySeat甚至也属于汽车座椅系列。任何此类限制和规则都需要在应用程序级别上强制实施,并且可能需要每天针对数据库运行一次运行状况检查查询以报告任何不匹配情况,以提供支持。 (主要座位的carID与carId不匹配的汽车)

© www.soinside.com 2019 - 2024. All rights reserved.