Entity Framework HasForeignKey ошибка с отношением 1: 1 - PullRequest
0 голосов
/ 21 февраля 2020

При настройке отношения один ко многим я могу сделать это, и оно работает:

EntityTypeBuilder<BrandOwner> brandOwner = X

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

В отношении 1: 1 я могу использовать этот синтаксис, и он работает (соблюдайте generi c 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 используется не-generi c HasForeignKey выдаст ошибку?

1 Ответ

0 голосов
/ 21 февраля 2020

Структура у вас не 1-к-1, это 1-ко-многим. 1-к-1, как правило, настроен на использование одного и того же идентификатора:

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

Для этого отношения потребуется идентификатор места в автомобиле:

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

Установка этого может быть возможной, но потребует явного сопоставления для всех отношений автомобиля и сиденья, вместо того, чтобы оставить это для соглашения. Car явно необходимо знать, как разрешить свою коллекцию Seats (в которой используется CarId on Seat) и разрешить экземпляр PrimarySeat. (многие-к-1) Это не один-к-одному, потому что ничто не мешает нескольким автомобилям указывать один и тот же SeatID в качестве основного. Кроме того, ничто не заставляет нас думать, что PrimarySeat даже принадлежит к коллекции автомобильных сидений. Любые такие ограничения и правила необходимо будет применять на уровне приложения, возможно, при поддержке запроса проверки работоспособности, ежедневно выполняемого для базы данных, чтобы сообщить о любых несоответствиях. (Автомобили с основными местами, у которых carId не совпадает)

...