Беглое отображение наследования

У меня есть проблема, для которой я не знаю лучшего решения. Надеюсь, кто-то здесь может помочь =)

Что я пытаюсь решить: мы должны вводить пользователей в систему, человека и организацию. Я хочу иметь общую таблицу входа для двоих (т. Е. Пользователь, вероятно, не будет знать, какого типа он пользователь, он просто связан с именем пользователя и паролем). Поэтому я создал таблицу входа в систему для имен пользователей и паролей. Но мне нужно знать, к кому подключен логин, поэтому мне нужна ссылка либо на человека, либо на организацию.

Рассмотрим следующие классы (упрощенно):

public class Login
{
    public string Username {get; set;}
    public string Password {get;set;}
}

public class LoginPerson : Login
{
    public Person Person {get;set;}
}

public class LoginOrg : Login
{
    public Organization Organization {get;set;}
}

public class Person
{
    public LoginPerson LoginPerson {get;set;}
    //Lots of other properties. Removed for simplicity
}

public class Organization
{
    public LoginOrg LoginOrg {get;set;}
    //Lots of other properties. Removed for simplicity
}

Конфигурация человека настроена следующим образом:

public class PersonConfiguration : EntityTypeConfiguration<Person>
    {
        public PersonConfiguration()
        {
            HasRequired(p => p.LoginPerson).WithRequiredPrincipal(p => p.Person);
        }
    }

Прежде всего, это не работает. Я получаю исключение: "System.Data.EntityCommandCompilationException: System.Data.EntityCommandCompilationException: при подготовке определения команды произошла ошибка. Подробности см. Во внутреннем исключении. ---> System.Collections.Generic.KeyNotFoundException: указанный ключ был отсутствует в словаре.."Итак, мой первый вопрос: почему это не работает? Мой второй вопрос: какая стратегия лучше всего подходит для такого рода наследования? TPT, TPH или TPC?

2 ответа

Решение

Решением для моего исключения было установить правильную конфигурацию;-) PersonConfiguration не нужно было включать какую-либо конфигурацию для свойства LoginPerson. Я добавил LoginPersonConfiguration ->

public class LoginPersonConfiguration : EntityTypeConfiguration<LoginPerson>
{
    public LoginPersonConfiguration()
    {
        ToTable("LoginPerson");
        HasKey(l => l.Id);
        HasRequired(l => l.Person).WithOptional(p => p.LoginPerson).Map(t => t.MapKey("PersonId")); 
    }
}

И я также должен был добавить Логин в класс DbContext

public class MyDbContext : DbContext
{
    public DbSet<Person> Persons { get; set; }
    public DbSet<Login> Logins { get; set; }
}

Когда речь заходит о том, какая стратегия лучше, я решил пойти на TPT.

Ну, для начала, ни у кого из ваших сущностей нет ключей. Вам нужен первичный ключ, чтобы заставить их работать. EF использует соглашение, чтобы сделать это, которое является именем класса плюс Id в конце, как PersonId, или вы должны быть явным с атрибутом [Key]

Во-вторых, ваша модель запутанная и довольно круглая. А без первичных ключей невозможно создать ассоциации.

Я запутался, почему у вас есть член, который является LoginPerson в объекте Person, и то же самое для Организации? В любом случае, вам действительно нужно переосмыслить эту модель и выяснить, какие у вас ключи.

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