2013-09-04 2 views
5

У меня есть программа, использующая базу данных Entity Framework (EF) Сначала на уровне доступа к данным. Я знаю, что для того, чтобы EF автогенерации навигационных свойств многих ко многим отношений, таблица отображения должна содержать только составной первичный ключ:Entity Framework много-много отношений с дополнительным полем (база данных сначала)

Project 
    - ProjectId (PK) 
    - Name 

ContentType 
    - ContentTypeId (PK) 
    - Name 

ProjectContentTypeMapping 
    - ProjectId (PK) 
    - ContentTypeId (PK) 

В этом случае все работает отлично, и я могу доступ к проектам из ContentTypes и наоборот с помощью свойств навигации.

Однако у меня есть требование иметь дополнительные поля, которые являются особыми для отношений между проектами и ContentTypes, и это будет дополнительные столбцы в таблице ProjectContentTypeMapping. Как только я их добавлю, я теряю свойства навигации, а EF отображает таблицу сопоставлений в дизайнере.

Можно ли вручную настроить сопоставление между этими двумя таблицами в EF (Database First)? В качестве альтернативы, как я могу это представить? Я думал, может быть, имея дополнительную «метаданные» таблица с FK в таблицу отображения, но он выглядит «Hacky» мне ...

Благодаря

ответ

7

Нет, вы не можете иметь дополнительные столбцов вашу таблицу отображения в структуре сущностей. Потому что, имея дополнительный столбец, вы намерены использовать его, но таблицы сопоставления не являются частью сущности, поэтому инфраструктура сущности больше не обрабатывает вашу таблицу сопоставления с дополнительными столбцами в качестве таблицы сопоставления. Вам придется манипулировать сопоставлениями вручную.

Давайте брать пример ваших классов:

Project 
    - ProjectId (PK) 
    - Name 
    - ProjectContents 

ContentType 
    - ContentTypeId (PK) 
    - Name 
    - ProjectContents 

ProjectContentTypeMapping 
    - ProjectId (PK) 
    - ContentTypeId (PK) 
    - OtherRelevantColumn 

где ProjectContents имеет тип ProjectContentTypeMapping

поэтому, когда вы добавляете проект с некоторыми ContentType, вы будете делать это:

Project prj = new Project(); 
//fill out scalar properties 
ProjectContentTypeMapping pctm = new ProjectContentTypeMapping(); 
pctm.ContentTypeId = 1; //or whatever you want, or selected from UI 

prj.ProjectContents = new ProjectContentTypeMapping(); 
prj.ProjectContents.Add(pctm); 

dataContext.Projects.Add(prj); 

Теперь, в случае редактирования (добавления ContentTypes) в существующий проект, вы не будете делать prj.ProjectContents = new ..., а вы сделаете это только тогда, когда это будет нуль, е,

if(prj.ProjectContents==null) 
    prj.ProjectContents = new ProjectContentTypeMapping(); 

также один очень и очень важно, так как теперь ваша ProjectContentTypeMapping больше не таблица отображения, поэтому удаление проекта не даст вам ошибку, если ее идентификатор присутствует в ProjectContentTypeMapping Таблица; вам необходимо будет удалить их вручную i.e

foreach(var pctm in prj.ProjectContents.ToList()) 
{ 
    prj.ProjectContents.Remove(pctm); 
    datacontext.ProjectContentTypeMappings.Remove(pctm); 
} 
datacontext.Remove(prj); 
datacontext.SaveChanges(); 
+0

Можете ли вы предоставить дополнительную информацию о том, как манипулировать отображениями вручную? – chuwik

+0

см. Мой anser @chuwik –

+3

Невозможно ли иметь дополнительные столбцы, но сказать, что Entity Framework обрабатывает таблицу так, как будто это не так? Чтобы как-то импортировать только две колонки вместо всей таблицы из базы данных? Мне нужны дополнительные столбцы в БД по другим причинам (политика на рабочем месте, другие приложения, которые используют одну и ту же базу данных), но мое приложение даже не должно знать о них. –