Ошибка EF-Migrations FK при попытке создания отношений между подтипами
Я моя модель домена у меня есть Company
базовый класс, который является абстрактным, и три различных типа компании, представленные подклассами компании:
public abstract class Company
{
public int Id { get; set; }
...
}
public class Supplier : Company
{
...
}
public class Dealer : Company
{
public DealerFundsAccount FundsAccount { get; set; }
...
}
public class Retailer : Company
{
public RetailerFundsAccount FundsAccount { get; set; }
...
}
Таким же образом у меня есть другой базовый класс, который определяет учетную запись фонда и два подтипа, которые реализуют определенные свойства:
public abstract class FundsAccount
{
public int Id { get; set; }
...
}
public class DealerFundsAccount : FundsAccount
{
public Dealer Dealer { get; set; }
...
}
public class RetailerFundsAccount : FundsAccount
{
public Retailer Retailer { get; set; }
...
}
Моя стратегия отображения для этих типов - таблица на иерархию, поэтому в моем классе DbContext я определяю только DbSets для базовых классов, что позволяет мне выполнять как полиморфные, так и неполиморфные запросы:
public DbSet<Company> Companies { get; set; }
public DbSet<FundsAccount> FundsAccounts { get; set; }
Теперь самое сложное, мои требования гласят:
- Поставщик не должен иметь денежный счет
- Дилер должен иметь DealerFunds Account
- У продавца должен быть RetailerFunds Account
Это должно быть так просто:
modelBuilder.Entity<Retailer>()
.HasRequired(r => r.FundsAccount)
.WithRequiredDependent(rfa => rfa.Retailer);
modelBuilder.Entity<Dealer>()
.HasRequired(d => d.FundsAccount)
.WithRequiredDependent(dfa => dfa.Retailer);
Но EF Migrations терпит неудачу, пытаясь обновить схему базы данных. Благодаря TPH дилеры и розничные продавцы отображаются в одну и ту же таблицу базы данных компании, а RetailerFundsAccounts и DealerFundsAccounts сопоставляются с таблицей базы данных Funds Account, и все это желательно, но поскольку я определил два взаимно-однозначных отношения между подтипами, EF пытается дважды определите внешний ключ для поля FundsAccount Id.
Я знаю, что могу взломать решение, определив отношение "один ко многим" для каждой из таблиц компании, у которой есть счет средств, и предотвращение поведения "один ко многим" с использованием уникальных ограничений в его FK, но я хотел уточнить у вас, есть лучшее решение.
1 ответ
Оказывается, виновата миграция EF. Если я пытаюсь создать схему базы данных с нуля, все в порядке, но если вы создаете миграцию для добавления этих сущностей, EF завершается неудачно, дважды пытаясь создать индекс и внешний ключ, например так:
CreateTable(
"dbo.FundsAccount",
c => new
{
Id = c.Int(nullable: false),
Discriminator = c.String(nullable: false, maxLength: 128),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.Company", t => t.Id)
.ForeignKey("dbo.Company", t => t.Id) // duplicate
.Index(t => t.Id)
.Index(t => t.Id); // duplicate
Решение состоит в том, чтобы отредактировать миграцию, удалив дублированные FK и индексные записи.
Я также обновлю название вопроса, чтобы лучше описать проблему.