Pracuję z bazą danych SQL Server z ponad 1000 tabel, jeszcze kilkaset widoków i kilka tysięcy procedur przechowywanych. Chcemy zacząć korzystać z Entity Framework w naszych nowszych projektach i pracujemy nad naszą strategią. To, na czym się rozłączam, polega na tym, jak najlepiej podzielić tabele na różne modele (EDMX lub DbContext, jeśli najpierw uruchomimy kod). Mogę od razu wymyślić kilka strategii:
- Podzielone według schematu
Mamy tabele podzielone na prawdopodobnie kilkanaście schematów. Możemy wykonać jeden model na schemat. Nie jest to jednak idealne, ponieważ dbo wciąż jest bardzo duże, z ponad 500 tabelami / widokami. Innym problemem jest to, że niektóre jednostki pracy będą musiały dokonywać transakcji obejmujących wiele modeli, co zwiększa złożoność, chociaż zakładam, że EF czyni to dość prostym. - Podziel według zamiarów
Zamiast martwić się o schematy, podziel modele według zamiarów. Będziemy więc mieć różne modele dla każdej aplikacji, projektu, modułu, ekranu, w zależności od tego, jak bardzo chcemy uzyskać szczegółowość. Problem, jaki tu widzę, polega na tym, że istnieją pewne tabele, które nieuchronnie muszą być używane w każdym przypadku, takie jak Użytkownik lub AuditHistory. Czy dodajemy je do każdego modelu (chyba narusza DRY), czy też są w osobnym modelu, który jest używany w każdym projekcie? - Nie dziel się wcale - jeden gigantyczny model
Jest to oczywiście proste z punktu widzenia rozwoju, ale z moich badań i mojej intuicji wydaje się, że może on działać strasznie, zarówno w czasie projektowania, podczas kompilacji, jak i w czasie wykonywania.
Jaka jest najlepsza praktyka używania EF przeciwko tak dużej bazie danych? W szczególności, jakie strategie stosują ludzie przy projektowaniu modeli w stosunku do tej liczby obiektów DB? Czy są opcje, o których nie myślę, że działają lepiej niż to, co mam powyżej?
Czy jest to również problem w przypadku innych ORM, takich jak NHibernate? Jeśli tak, to czy wymyślili jakieś lepsze rozwiązania niż EF?
źródło
Odpowiedzi:
Osobiście próbowałem stworzyć jeden ogromny schemat dla wszystkich moich bytów w dość złożonym, ale małym projekcie (~ 300 tabel). Mieliśmy bardzo znormalizowaną bazę danych (normalizacja 5. formy (mówię to luźno)) z wieloma relacjami „wiele do wielu” i ekstremalnym wymuszaniem integralności referencyjnej.
Zastosowaliśmy także strategię „pojedynczej instancji na żądanie”, która nie jest przekonana, że pomogła.
Podczas wykonywania prostych, stosunkowo płaskich „wyraźnie zdefiniowanych” list, wyszukiwania i zapisywanie wydajności było ogólnie akceptowalne. Ale kiedy zaczęliśmy wnikać w głębokie relacje, występ wydawał się gwałtownie spadać. W porównaniu do przechowywanego proc w tym przypadku nie było porównania (oczywiście). Jestem pewien, że moglibyśmy ulepszyć bazę kodu tu i tam, aby poprawić wydajność, jednak w tym przypadku potrzebowaliśmy tylko zwiększenia wydajności bez analizy ze względu na ograniczenia czasowe, i wróciliśmy do przechowywanego proc (wciąż go zmapowano) poprzez EF, ponieważ EF dawał mocno typowane wyniki), potrzebowaliśmy tego tylko jako cofnięcia w kilku obszarach. Kiedy musieliśmy przeglądać całą bazę danych, aby utworzyć kolekcję (bez oszczędnego używania .include ()), wydajność wyraźnie spadła, ale może chcieliśmy za dużo ...
Tak więc na podstawie mojego doświadczenia zaleciłbym utworzenie osobnego pliku .edmx dla każdego celu. Generuj tylko to, czego będziesz używać, na podstawie zakresu tej potrzeby. Możesz mieć kilka mniejszych plików .edmx do zadań specjalnych, a następnie kilka dużych, w których musisz przechodzić złożone relacje, aby budować obiekty. Nie jestem pewien, gdzie jest to magiczne miejsce, ale jestem pewien, że jest jeden ... lol ...
Szczerze mówiąc, oprócz kilku pułapek, które widzieliśmy (skomplikowane przechodzenie), ogromny plik .edmx działał dobrze z „działającej” perspektywy. Ale musisz uważać na magię „naprawiania”, jaką robi kontekst za sceną, jeśli nie wyłączasz jej jawnie. Oprócz utrzymywania synchronizacji pliku .edmx podczas wprowadzania zmian w bazie danych .. czasami łatwiej było wyczyścić całą powierzchnię i ponownie utworzyć obiekty, co zajęło około 3 minut, więc nie było to wielkim problemem.
Wszystko to było dzięki EntityFramework 4.1. Bardzo chciałbym usłyszeć o twoim ostatecznym wyborze i doświadczeniu.
A jeśli chodzi o twoje pytanie dotyczące nHibernate, moim zdaniem jest to pytanie o puszkę robaków, będziesz szczekał po obu stronach ogrodzenia ... Słyszę, że wiele osób walczy EF w celu walenia bez pracy przez wyzwania i zrozumienie niuansów charakterystycznych dla samej EF .. i chociaż nigdy nie korzystałem z nHibernate w produkcji, ogólnie rzecz biorąc, jeśli musisz ręcznie i jawnie tworzyć takie rzeczy jak mapowania, uzyskasz większą skończoną kontrolę, jeśli jednak mogę przeciągać i upuszczać, generować i uruchamiać CRUD'ing i kwerendy za pomocą LINQ, mogę dać bzdury na temat ziarnistości.
Mam nadzieję, że to pomoże.
źródło
Zacznę od prostego wyjaśnienia: nie mam doświadczenia z tak dużą bazą danych, więc reszta mojej odpowiedzi nie jest oparta na przykładzie z prawdziwego świata.
Masz więc dużą bazę danych i chcesz jej używać z ORM / EF. Wybrałbym drugi wybór. Oto moje proste wyjaśnienie, dlaczego:
źródło
Powiedziałbym, że nie możesz zdecydować się na tego rodzaju pytanie z technicznego punktu widzenia. Radziłbym zbudować architekturę w oparciu o przypadki użycia (historie użytkowników itp.). Najpierw znajdź swoje obiekty biznesowe. Obiekt encji nie jest domyślnie obiektem biznesowym. Typowo będziesz mieć obiekt biznesowy przed obiektami encji. Następnie możesz stopniowo decydować, czego naprawdę potrzebujesz, na podstawie wymagań użytkownika.
„Dobry architekt maksymalizuje liczbę niepodejmowanych decyzji”. Robert C. Martin
http://cleancoder.posterous.com/architecture-deference
źródło
Używam podejścia hybrydowego - operacje OLTP są obsługiwane przez EF, podczas gdy ciężkie operacje, takie jak wstawianie partii, masowe aktualizacje, zapytania raportów itp. Są obsługiwane przez przechowywane procesy. Ułatwia także ścieżkę migracji, jeśli nie wykonujesz pełnego ponownego zapisu warstwy danych naraz.
źródło