Как я могу использовать модели наследования TPT, если первичные ключи имеют разные имена?

Используя Entity Framework 4.1 для устаревшей базы данных, я не могу создать рабочий набор моделей наследования TPT, которые не являются множественными и используют разные имена для общего первичного ключа.

Я использую таблицы базы данных Organization, Account и Company, как показано ниже:

Organization
  OrganizationID (int PK)
  OrgName (varchar)

Company
  CompanyID (int PK)
  CompanyNo (varchar)

Account
  AccountID (int PK)
  AccountNo (varchar)

Account.AccountID и Company.CompanyID имеют ограничение FK, согласно которому значения в этих столбцах также должны содержаться в Organization.OrganizationID, поэтому ни один из них не может существовать без строки Organization. Если бы я разрабатывал эти таблицы с нуля, и Account, и Company вместо этого использовали бы OrganizationID в качестве первичного ключа.

public partial class BusinessEntities : DbContext
{
    public BusinessEntities()
        : base("name=BusinessEntities")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Organization>().ToTable("Organization");

        // Override pluralization
        modelBuilder.Entity<Company>().ToTable("Company");
        modelBuilder.Entity<Account>().ToTable("Account");

        // Set primary key column for each
        modelBuilder.Entity<Company>().Property(
            e => e.OrganizationID).HasColumnName("CompanyID");
        modelBuilder.Entity<Account>().Property(
            e => e.OrganizationID).HasColumnName("AccountID");
    }

    public DbSet<Organization> Organization { get; set; }
}

public partial class Organization
{
    public int OrganizationID { get; set; }
    public string OrgName { get; set; }
}

public partial class Account : Organization
{
    public string AccountNo { get; set; }
}

public partial class Company : Organization
{
    public string CompanyNo { get; set; }
}

Когда я пытаюсь использовать простой код выбора, указанный ниже, я получаю сообщение об ошибке:

Свойство «OrganizationID» не является объявленным свойством типа «Компания». Убедитесь, что свойство не было явно исключено из модели с помощью метода Ignore или аннотации данных NotMappedAttribute. Убедитесь, что это допустимое примитивное свойство.

static void Main(string[] args)
{
    using (var context = new BusinessEntities())
    {
        foreach (var b in context.Organization.OfType<Company>())
        {
            Console.WriteLine("{0} {1}", b.CompanyNo, b.OrgName);
        }

        foreach (var b in context.Organization.OfType<Account>())
        {
            Console.WriteLine("{0} {1}", b.AccountNo, b.OrgName);
        }
    }
    Console.ReadLine();
}

person vees    schedule 30.03.2011    source источник
comment
Это наследование TPT (таблица для каждого типа), а не TFT.   -  person Ladislav Mrnka    schedule 30.03.2011


Ответы (1)


Я описал сопоставление TPT здесь< /а>. Это шаг за шагом, поэтому он должен работать, но вам нужно сопоставить идентификаторы в дочерних объектах.

Но проблема в том, что вы начинаете с Model-first, генерируете DdContext, который зависит от EDMX, затем удаляете этот EDMX и начинаете определять сопоставление самостоятельно. Вы должны решить, хотите ли вы использовать Model-first или Code-first. Вы просто зря потратили свои усилия на EDMX.

Если вы хотите узнать, как использовать Model-first с DbContext, проверьте этой статьи. Если вы хотите использовать Code-first, не создавайте EDMX и следуйте этой статье, чтобы сопоставить свое наследование.

person Ladislav Mrnka    schedule 30.03.2011
comment
Это также происходит, если я использую четыре указанных выше класса, даже не определив их в EDMX. В первой статье кода, о которой вы упоминаете, похоже, ничего не говорится о том, как редактировать модель или украшать классы POCO, чтобы они могли использовать CompanyID и AccountID в качестве первичных ключей без их переименования, но, возможно, я что-то упустил. - person vees; 31.03.2011