EF Db Первый подход - работа с таблицами без ПК - PullRequest
0 голосов
/ 02 января 2019

Я попытался создать контекст для существующей базы данных, используя метод db first, и получил ошибку ниже:

// Невозможно сгенерировать тип сущности для таблицы 'dbo.TT_ProjectMembers'.Пожалуйста, смотрите предупреждающие сообщения.Невозможно определить первичный ключ для таблицы 'dbo.TT_ProjectMembers'.Невозможно сгенерировать тип сущности для таблицы 'dbo.TT_ProjectMembers'.

Таблица TT_ProjectMembers содержит два столбца: ProjectId (int) UserId (int).К сожалению, у меня нет возможности обновить базу данных (добавить новые столбцы и т. Д.).

Я решил создать сущность и все остальное вручную.Я решил установить составной ключ для этой таблицы, потому что это просто имеет смысл - неправильно иметь 2 строки с одинаковым ProjectId и UserId.

//entity class

    public class ProjectMember
    {
        public int ProjectID { get; set; }
        public int UserID { get; set; }

    }

    //dbcontext property
    public virtual DbSet<ProjectMember> ProjectMembers { get; set; }    

    // entity config
        modelBuilder.Entity<ProjectMember>(entity =>
    {
        entity.ToTable("TT_ProjectMembers");
        entity.HasKey(p => new {p.ProjectID, p.UserID});
    });

Удивительно, но это сработало.Теперь я могу делать любые операции CRUD, но у меня есть несколько вопросов:

  1. Есть ли какие-либо недостатки или проблемы из-за такого решения проблемы?Как вы обычно решаете эту проблему?
  2. Почему EF требует, чтобы вы держали PK на столе?
  3. Как EF работает под капотом?(Я знаю, что это широкий вопрос, поэтому любые советы по книге / статье будут оценены по достоинству)

1 Ответ

0 голосов
/ 02 января 2019

1) Вот так. Таблицы-посредники, которые разбивают отношение M: M на два 1: M, должны иметь два столбца внешнего ключа в качестве своего PK. Создание таких таблиц с третьим столбцом PK

- ошибка новичка

2) Потому что именно так он ищет связанные данные, когда вы их запрашиваете (employee.Company.Name может привести к загрузке данных компании для этого сотрудника, поэтому, возможно, что-то вроде SELECT Company.* FROM Company JOIN Employee ON Company.ID = Employe.CompanyId WHERE Employee.Id = @id или, если объединения не используются запрашивая CompanyId у этого сотрудника, затем запрашивая данные о компании из ID компании), и как он точно знает, что он обновляется только в строке при сохранении изменений. «Нет ПК, нет игры!»

3) Боюсь, что это слишком широко для SO, но не стесняйтесь искать ресурсы, показывающие, как активировать ведение журнала генерируемых им запросов, тогда вы сможете увидеть, когда вы выполните context.Employee.Where(e => e.Name = "John"), как это делается SELECT x FROM Employee WHERE name = 'John' и т. Д.

...