Ошибка 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 и индексные записи.

Я также обновлю название вопроса, чтобы лучше описать проблему.

Другие вопросы по тегам