2010-03-15 11 views
5

Chciałbym zaimplementować MVC podczas używania LINQ (w szczególności LINQ-to-entity). Sposób, w jaki to zrobię, polega na tym, że kontroler generuje (lub wywołuje coś, co generuje) zestaw wyników za pomocą LINQ, a następnie zwraca go do widoku, aby wyświetlić dane. Problemem jest to, jeśli zrobić:Prosty sposób na zwracanie anonimowych typów (aby umożliwić MVC przy użyciu LINQ)

return (from o in myTable select o); 

Wszystkie kolumny są odczytywane z bazy danych, nawet te (potencjalnie dziesiątki) nie chcę. I - co ważniejsze - I nie może zrobić coś takiego:

return (from o in myTable select new { o.column }); 

ponieważ nie ma sposobu, aby anonimowe typy typu bezpieczny! Wiem na pewno, że nie ma ładnego, czystego sposobu robienia tego w 3.5 (this nie jest czysty ...), , ale co z wersją 4.0? Czy jest coś zaplanowanego, a nawet zaproponowane? Bez czegoś takiego jak typowanie kodem dla LINQ lub bezpieczne anonimowe wartości zwracane (wydaje mi się, że kompilator powinien z pewnością być zdolny do tego), wydaje się prawie niemożliwe, aby oczyścić kontroler z widoku.

+0

Podczas pracy z użytkownikiem należy się przyzwyczaić do tego, że sql wybiera wszystkie kolumny tabeli. Jeśli piszesz zapytania, które wybiera tylko kilka, możesz równie dobrze używać sql. Jeśli masz mnóstwo obiektów na swoich obiektach, to jest to twój problem. Twoje obiekty powinny być mniejsze i powinieneś pomyśleć o tym, jak to naprawić. Anonimowe typy nie powinny być przekazywane, a nie jako modele do widoku. –

+0

@Mattias: Niestety, życie nie jest takie proste. Na przykład rozważmy przypadek, w którym wybieram kilka kolumn z różnych tabel, w tym tablicę obiektów wybranych przy użyciu zapytania wewnętrznego LINQ. O ile mi wiadomo, nie ma możliwości zwrócenia tego jako pojedynczego obiektu EF - to * ma * być nowym typem, a definiowanie nowego typu betonu dla każdego zapytania jest absurdalnie nieporęczne. –

+0

Brzmi dla mnie tak, jakbyś miał całkiem kiepski model. Twój obiekt powinien mieć referencje, których potrzebuje i możesz po prostu użyć metody "Include()" w EF (aby szybko załadować te dane). Jeśli przestaniesz myśleć o danych jako o różnych kolumnach w różnych tabelach, a więcej o swoim modelu (więcej OO), najprawdopodobniej będzie o wiele łatwiej pracować. Konkluzja: Jeśli uważasz, że musisz omijać anonimowe typy, najprawdopodobniej zrobisz coś złego. –

Odpowiedz

1

Ponieważ nikt nawet nie próbował odpowiedzieć na moje pytanie, będę go odebrać sobie ..

Okazuje się, C# 4.0 obsługuje kaczego pisanie - nazywają go dynamic typing. Jednak w użyciu dynamicznych rodzajów wrócić anonimowych typów, tracimy korzyści z silnych typów:

  • kompilacji
  • Wydajność
  • Intellisense

mam otwarte typu sprawdzanie żądanie funkcji, aby uzyskać anonimowe typy zwrotów o silnym typie: here - jeśli uważasz, że jest to użyteczne uzupełnienie C# 5, kliknij link i poinformuj zespół .Net!

3

Typy anonimowe są zaprojektowane przede wszystkim do stosowania w ramach metody. Nie nadają się do komunikacji między metodami.

Jeśli trzeba przejść przez zbiór danych pomiędzy dwoma funkcjami najlepszym sposobem jest stworzenie nowego typu owijanie danych lub użyć przegrany grupowania jak Tuple<T1,T2> lub KeyValuePair<TKey,TValue>

+0

z wyjątkiem scenariusza opartego na refleksji, w którym to przypadku istnieje kilka dobrych zastosowań dla nich (na przykład w pomocniku HTML dla haseł MVC) –

+0

@Jared: Tyle tylko, że z LINQ to w ogóle nie jest prawdą - obiekty LINQ z pewnością mają być przekazywane, ale po prostu nie można tego zrobić w języku C# ze względu na ograniczenia językowe. Jednak * może * być wykonane w VB.net. –

+0

@ BlueRaja, przepraszam, że to niepoprawne. ** Mogą ** być przekazywane w obu językach jako 'System.Object'. Nie można ich silnie przekazywać w obu językach, ponieważ typy anonimowe są dobrze anonimowe. Nie można ich zdefiniować bezpośrednio w żadnym miejscu, które pojawią się w metadanych. W VB.net (i C# 4.0) można obejść ten problem, uzyskując dostęp do nich w słabo napisany sposób, ale nie jest to tym, o co prosi OP. – JaredPar

4

Użyj warstwę widoku modelu. Twój widok musi wiedzieć, co zamierza wyświetlić. Myślę, że jest to możliwe, aby utworzyć widok, który po prostu formatuje wielowymiarową tablicę danych, ale to nie jest najlepszy powód, aby pójść z rozwiązaniem MVC. Możesz jednak wypełnić model widoku anonimowym obiektem do konsumpcji w widoku.

2

Co powiesz na to?

Zakładam, że masz klasę encji dla tabeli "myTable" (nazwijmy ją "MyTableEntity"), więc dlaczego nie stworzysz nowego obiektu MyTableEntity i nie użyjesz inicjalizatora obiektu do wypełnienia tylko tych kolumn, które chcesz?

return (from o in myTable select new MyTableEntity { AColumn = o.column }); 

To nie przełoży się SELECT * jak pytasz, ale nadal będziesz mieć sposób, aby zdać silnie wpisany obiekt do widzenia.

Musisz uważać, aby po prostu użyć zainicjowanych właściwości wewnątrz widoku i to wszystko.

Czy ma to dla ciebie sens?

+0

To dobry pomysł - wypróbuję to w pracy, gdy dostanę szansę (przynajmniej na kilka dni) –

0

Anonimowe typy .NET 4.0 można z łatwością przekonwertować na ExpandoObjects, dzięki czemu wszystkie problemy zostają wyeliminowane przez koszty samej konwersji. Sprawdź here

0

można łatwo przekonwertować do anonimowych typów obiektów dynamicznych, tutaj jest prosta implementacja Donymous obiektów (Dynamic anonimowych obiektów), które mogą zamieszkujących od obiektu anonimowych lub DataReader.

Powiązane problemy