2013-09-04 19 views
9

Próbuję użyć dwóch różnych podmiotów przeciwko tej samej tabeli. Celem posiadania dwóch jednostek jest ograniczenie ilości atrybutów w jednym z nich, ponieważ na jednej z form edycji powinna istnieć możliwość zmiany tylko kilku atrybutów.Jak zmapować wiele jednostek do jednej tabeli?

Aby uniknąć ukrywania atrybutów nieedytowalnych w celu zachowania ich wartości, pomyślałem, że dobrym pomysłem będzie posiadanie osobnej jednostki z tylko częścią atrybutów.

Więc mam jedną całość z wszystkimi atrybutami i jedną z niektórymi atrybutami. Problemem jest to, że otrzymuję ten wyjątek:

`typów jednostki ApplicationMapping 'i„ApplicationMappingFull” nie mogą dzielić stół„ApplicationMapping”, ponieważ nie są one w samej hierarchii typu lub nie posiada ważnej jednego na jeden klucz obcy związek z pasującymi kluczami podstawowymi między nimi.

Klasy config jednostka wyglądać następująco:

class ApplicationMappingFullConfiguration : EntityTypeConfiguration<ApplicationMappingFull> 
{ 
    public ApplicationMappingFullConfiguration() 
    { 
    ToTable("ApplicationMapping"); 
    HasKey(p => p.Id); 
    } 
} 

class ApplicationMappingConfiguration : EntityTypeConfiguration<ApplicationMapping> 
{ 
    public ApplicationMappingConfiguration() 
    { 
    ToTable("ApplicationMapping"); 
    HasKey(p => p.Id); 
    } 
} 

Jak mogę osiągnąć to, co mam zrobić? Czy istnieje lepszy/prostszy sposób robienia tego?

Dzięki!

+0

Czy "ApplicationMappingFull" dziedziczy po 'ApplicationMapping'? Czy możesz dodać kod do tych lekcji na swoje pytanie? –

+0

@HenkMollema Nie, nie ma dziedzictwa między jednostkami. Są to oddzielne jednostki, jedna ma wszystkie pola z tabeli, druga ma tylko kilka pól. – Stian

+0

Wystarczy użyć dwóch osobnych modeli widoku, które jednocześnie odwzorowują na tę samą jednostkę. – dotjoe

Odpowiedz

4

Polecam posiadanie pojedynczego elementu odwzorowanego na tabelę, ale utwórz dwie jednostki widoku, które zawierają tylko te właściwości, których wymaga formularz.

Te jednostki widoku mogą zawierać metody mapowania danych wprowadzanych z powrotem do jednostki podstawowej.

+0

Dzięki, spróbuję tej metody. – Stian

+0

Możesz chcieć użyć google do wzorca MVVM (Model - Widok - Widok modelu), ponieważ to właśnie tutaj patrzysz. – Paddy

-1

Twoje pytanie ma odpowiedź.

The entity types 'ApplicationMapping' and 'ApplicationMappingFull' cannot share table 'ApplicationMapping' 

Podczas mapowania typu jednostki do stołu, definiowania schematu dla tabeli. Jak powiedziałeś, masz jedną całość z wszystkimi atrybutami i jedną z pewnymi atrybutami. Po odwzorowaniu encji na tabelę należy zmapować wszystkie kolumny tabeli.

Tak więc w jednej linii "Nie jest możliwe".

Aby osiągnąć rozwiązanie swojego problemu, możesz zrobić to, co zaproponował Paddy. W przeciwnym razie można utworzyć klasę bazową z minimalnymi wymaganymi atrybutami, a następnie rozszerzyć tę klasę i dodać pozostałe atrybuty. Podczas przekazywania modelu do widoku należy przekazać obiekt klasy podstawowej. Można jednak użyć rozszerzonego obiektu klasy podczas pobierania rekordu z bazy danych.

3

Wygląda na to, że szukasz TPH (Table Per Hierarchy). Jest to relacyjny wzór dziedziczenia, w którym klasa i wszystkie jej podklasy mają tę samą tabelę i są obsługiwane natywnie przez Entity Framework. W rzeczywistości, jeśli wszystko co robisz, to jedna jednostka dziedziczy po innej, Entity Framework domyślnie wdraża ten wzorzec. W ogóle nie musisz robić nic specjalnego.

Istnieje jednak warunek: ponieważ właściwości w klasie bazowej muszą wystarczyć, aby można było pomyślnie zapisać wiersz w bazie danych, wszystkie właściwości podklasy muszą być opcjonalne - przynajmniej na poziomie poziom bazy danych.Zawsze można wymusić jedną lub więcej właściwości, które będą wymagane przez interfejs użytkownika interfejsu.

UPDATE

Rozszerzenie na moim komentarzu poniżej, jeśli wszystkie szukasz zrobić, to zwrócić podzbiór danych z tabeli, a następnie masz już wszystkie potrzebne narzędzia. Nie potrzebujesz dwóch oddzielnych elementów, tylko jednego obiektu (w tym przypadku twojej klasy ApplicationMappingFull), a następnie możesz użyć LINQ, aby zwrócić tylko te kolumny, których potrzebujesz.

db.ApplicationMappingFulls.Select(m => new ApplicationMappingViewModel 
    { 
     SomeProperty = m.SomeProperty, 
     OtherProperty = m.OtherProperty 
    }); 

Za kulisami EF wyda kwerendę, która będzie wybrać tylko SomeProperty i OtherProperty kolumn, bo to wszystko, co jest potrzebne. Twój model widoku nie byłby w ogóle połączony z EF; to tylko klasa przechowująca dane zwrócone przez EF.

+0

Hej, próbowałem użyć dziedziczenia, ale teraz otrzymałem wyjątek, który mówi, że potrzebuję kolumny "Dyskryminator". Rozumiem cel tej kolumny, ale nie ma różnicy między klasą podstawową a podklasą. Chcę po prostu pobrać wiersz z tabeli i przedstawić go za pomocą obiektu z kilkoma kolumnami, a przy innej okazji uzyskać ten sam wiersz ze wszystkimi kolumnami. Dane są takie same w obu okazjach, a wszystkie wiersze w tabeli są tego samego typu. – Stian

+0

Jeśli mówisz tylko o tym, że chcesz wyświetlać mniejszą ilość informacji z bazy danych, nie powinieneś mieć do czynienia z dwoma podmiotami w ogóle. Za pomocą LINQ możesz wybrać tylko kolumny, które chcesz, a EF wyda je na poziomie bazy danych. Następnie możesz zwrócić anonimowy obiekt tylko tych właściwości lub lepiej odwzorować go na model widoku. –

+0

W porządku, dzięki! – Stian

1

Inną alternatywą jest to, że jedna klasa wywodzi się od drugiej i ukrywa lub w inny sposób niszczy pola, które nie pozwalają na edycję.

Jako przykład ...

class Full { 
    public string ValueA {get;set;} 
} 

class Limited : Full { 
    public new string ValueA {get; private set;} 
} 

To nie jest wprawdzie największym rozwiązanie, ale innego wyboru można użyć.

Powiązane problemy