2013-09-04 43 views
5

Mam program używający Entity Framework (EF) Database Najpierw w warstwie dostępu do danych. Wiem, że aby EF do automatycznego wygenerowania właściwości nawigacyjnych wiele do wielu relacji, tabela mapowania musi zawierać tylko kompozytowy klucz podstawowy:Entity Framework wiele do wielu relacji z dodatkowym polem (najpierw baza danych)

Project 
    - ProjectId (PK) 
    - Name 

ContentType 
    - ContentTypeId (PK) 
    - Name 

ProjectContentTypeMapping 
    - ProjectId (PK) 
    - ContentTypeId (PK) 

W tym przypadku wszystko działa poprawnie i mogę dostęp do projektów z ContentTypes i odwrotnie dzięki właściwościom nawigacji.

Mam jednak wymóg posiadania dodatkowych pól, które są specyficzne dla relacji między projektami i elementami ContentTypes, a to byłoby dodatkowe kolumny w tabeli ProjectContentTypeMapping. Po dodaniu ich tracę właściwości nawigacji, a EF pokazuje tabelę mapowania w projektancie.

Czy istnieje sposób ręcznego skonfigurowania mapowania między tymi dwoma tabelami w EF (baza danych)? Alternatywnie, jak mogę to przedstawić? Myślałam o konieczności może dodatkowo „metadane” stół z FK do tabeli odwzorowania, ale wygląda na „hacky” do mnie ...

Dzięki

Odpowiedz

7

Nie, nie można mieć dodatkowych kolumn Twoja tablica mapowania w strukturze encji. Ponieważ posiadanie dodatkowej kolumny oznacza, że ​​zamierzasz z niej korzystać, ale tabele odwzorowań nie są częścią jednostki, więc struktura obiektu nie traktuje już tablicy odwzorowań z dodatkowymi kolumnami jako tabela odwzorowania. Będziesz musiał manipulować mapowaniem ręcznie.

Weźmy przykład ze swoich klas:

Project 
    - ProjectId (PK) 
    - Name 
    - ProjectContents 

ContentType 
    - ContentTypeId (PK) 
    - Name 
    - ProjectContents 

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

gdzie ProjectContents jest typu ProjectContentTypeMapping

więc gdy dodasz projekt z pewnymi contenttype, byś robił to:

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); 

Teraz, w przypadku edycji (dodawania elementów ContentTypes) do istniejącego projektu, nie będziesz wykonywać prj.ProjectContents = new ... raczej robisz to tylko wtedy, gdy jest zerowy i, e,

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

także jedna bardzo ważna rzecz, ponieważ teraz swoją ProjectContentTypeMapping nie jest już tabela mapowania, więc usuwanie projekt nie daje błąd, jeśli jego id to występuje w ProjectContentTypeMapping stół; będziesz musiał usunąć je ręcznie, np.

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

Czy możesz podać więcej informacji na temat ręcznego manipulowania mapowaniem? – chuwik

+0

zobacz mój anser @chuwik –

+3

Czy nie jest możliwe, aby dodatkowe kolumny, ale powiedzieć Entity Framework traktować tabelę tak, jakby nie? Aby jakoś zaimportować tylko dwie kolumny zamiast całej tabeli z bazy danych? Potrzebuję dodatkowych kolumn w bazie danych z innych powodów (zasady dotyczące miejsca pracy, inne aplikacje korzystające z tej samej bazy danych), ale moja aplikacja nie musi ich nawet znać. –