Najpierw kod vs Model / najpierw baza danych [zamknięte]

618

Jakie są zalety i wady korzystania z Entity Framework 4.1 Najpierw kod nad Model / Baza danych najpierw ze schematem EDMX?

Staram się w pełni zrozumieć wszystkie podejścia do budowania warstwy dostępu do danych przy użyciu EF 4.1. Używam wzorca repozytorium i IoC.

Wiem, że mogę zastosować podejście oparte na kodzie: ręcznie definiuj moje byty i kontekst oraz używaj ModelBuilderdo dostrajania schematu.

Mogę również utworzyć EDMXdiagram i wybrać krok generowania kodu, który używa szablonów T4 do generowania tych samych POCOklas.

W obu przypadkach kończę na POCOobiekcie ORMagnostycznym i pochodzącym z kontekstu DbContext.

Najpierw baza danych wydaje się być najbardziej atrakcyjna, ponieważ mogę zaprojektować bazę danych w Enterprise Manager, szybko zsynchronizować model i dostosować go za pomocą projektanta.

Jaka jest różnica między tymi dwoma podejściami? Czy chodzi tylko o preferencje VS2010 vs Enterprise Manager?

Jakub Konecki
źródło
12
Entity Framework 7 upuszcza EDMX: msdn.microsoft.com/en-us/magazine/dn890367.aspx
CAD
5
@CADbloke Entity Framework 7 to teraz Entity Framework Core 1.0
RBT
6
Do wszystkich innych przeglądarek, chyba że masz hardon na 7000 długich plików XML i rozwiązywanie konfliktów scalania we wspomnianym wyżej, idź najpierw kod i oszczędzaj sobie bólu głowy
Dan Pantry
3
Jest to dobry stycznia 2015 write-up na trzech podejść w roland.kierkels.net/c-asp-net/...
danio
4
Prawie każda udzielona odpowiedź to „Myślę” … absolutna definicja „przede wszystkim opinii”.
Lankymart,

Odpowiedzi:

703

Myślę, że różnice są następujące:

Najpierw kod

  • Bardzo popularny, ponieważ hardcorowi programiści nie lubią żadnych projektantów, a definiowanie mapowania w EDMX xml jest zbyt skomplikowane.
  • Pełna kontrola nad kodem (brak kodu generowanego automatycznie, który jest trudny do modyfikacji).
  • Ogólne oczekiwania są takie, że nie przejmujesz się DB. DB to tylko pamięć bez logiki. EF zajmie się tworzeniem i nie chcesz wiedzieć, jak to działa.
  • Ręczne zmiany w bazie danych zostaną najprawdopodobniej utracone, ponieważ kod definiuje bazę danych.

Najpierw baza danych

  • Bardzo popularny, jeśli masz DB zaprojektowany przez DBA, opracowany osobno lub jeśli masz już DB.
  • Pozwolisz EF tworzyć encje dla ciebie, a po modyfikacji mapowania wygenerujesz encje POCO.
  • Jeśli chcesz dodatkowych funkcji w jednostkach POCO, musisz zmodyfikować szablon T4 lub użyć klas częściowych.
  • Ręczne zmiany w bazie danych są możliwe, ponieważ baza danych określa model domeny. Zawsze możesz zaktualizować model z bazy danych (ta funkcja działa całkiem dobrze).
  • Często używam tego razem z projektami VS Database (tylko wersja Premium i Ultimate).

Najpierw model

  • IMHO popularne, jeśli jesteś fanem projektantów (= nie lubisz pisać kodu lub SQL).
  • „Narysujesz” swój model i pozwolisz, aby przepływ pracy wygenerował skrypt bazy danych, a szablon T4 wygenerował byty POCO. Stracisz część kontroli zarówno nad swoimi jednostkami, jak i bazą danych, ale w przypadku małych łatwych projektów będziesz bardzo produktywny.
  • Jeśli chcesz dodatkowych funkcji w jednostkach POCO, musisz zmodyfikować szablon T4 lub użyć klas częściowych.
  • Ręczne zmiany w bazie danych zostaną najprawdopodobniej utracone, ponieważ model definiuje bazę danych. Działa to lepiej, jeśli masz zainstalowany pakiet zasilania generowania bazy danych. Umożliwi to aktualizację schematu bazy danych (zamiast odtwarzania) lub aktualizację projektów baz danych w VS.

Oczekuję, że w przypadku EF 4.1 istnieje kilka innych funkcji związanych najpierw z Kodem vs. Model / Baza danych. Płynne API użyte w Code najpierw nie oferuje wszystkich funkcji EDMX. Oczekuję, że funkcje takie jak mapowanie procedur przechowywanych, widoki zapytań, definiowanie widoków itp. Będą DbContextdziałać, gdy najpierw użyję Modelu / Bazy danych i (jeszcze tego nie próbowałem), ale najpierw nie działają w Kodzie.

Ladislav Mrnka
źródło
5
@Ladislav - dziękuję za wyczerpującą odpowiedź. Wyjaśnij: poza pewnymi ograniczeniami płynnego API nie ma rzeczywistych różnic technicznych między tymi podejściami? Chodzi o proces rozwoju / wdrażania / metodologię? Na przykład mam osobne środowisko dla Dev / Test / Beta / Prod i zaktualizuję bazę danych ręcznie na Beta / Prod, ponieważ zmiany w schemacie mogą wymagać pewnych skomplikowanych modyfikacji danych. Dzięki Dev / Test cieszę się, że EF upuszcza i tworzy bazy danych, ponieważ sam zainicjuję je danymi testowymi w inicjalizatorach.
Jakub Konecki
152
Projektuję bazy danych od tak dawna, że ​​wydaje mi się, że nie wyobrażam sobie, żebym kiedykolwiek najpierw zrobił coś innego. W rzeczywistości wciąż piszę wiele procedur przechowywanych dla instrukcji wyboru o większej objętości i tak dalej, a następnie zrobię import funkcji do modelu EF, wszystko w imię wydajności.
Steve Wortham
9
Co masz na myśli mówiąc o dużej ilości instrukcji select? Procedury przechowywane nie są szybsze niż SELECTs wysyłane z aplikacji.
Piotr Perak,
20
Państwo może mieć SQL w aplikacji. Ten kod SQL najprawdopodobniej zostanie osadzony w skompilowanym kodzie, a wszelkie zmiany będą wymagały ponownej kompilacji i ponownego wdrożenia, podczas gdy zmiana Procedury składowanej będzie wymagała jedynie edycji Procedury składowanej. Klienci / Klienci / Użytkownicy będą mniej dotknięci zmianami w tym przypadku.
CodeWarrior,
5
@JakubKonecki, cokolwiek nie znajdziesz w tych, DbContextktóre istnieją w ObjectContextużyciu ((IObjectContextAdapter)dbcontext).ObjectContext.
Shimmy Weitzhandler
134

Myślę, że to proste „drzewo decyzyjne” Julie Lerman, autorki „Programming Entity Framework” powinno pomóc w podejmowaniu decyzji z większą pewnością:

drzewo decyzyjne pomagające w wyborze różnych podejść do EF

Więcej informacji tutaj .

Bahador Izadpanah
źródło
111
To nie jest kompletne. Co jeśli wolisz NIE używać projektanta wizualnego, ale masz już bazę danych?
Dave New
14
Co gorsza ... rzeczywiste decyzje nie są podejmowane za pomocą diagramów, a raczej ograniczeń technicznych, które napotykasz podczas korzystania z kodu, np. Nie możesz utworzyć unikalnego indeksu na polu lub nie możesz usunąć danych hierarchicznych w tabeli drzewa dla tego potrzebujesz CTE za pomocą kontekstu.Tabela.SqlQuery („wybierz ...”). Model / baza danych po pierwsze nie mają tych wad.
Elisabeth,
32
@davenewza to pierwsza ścieżka, prawda?
Chris S
3
@davenewza istniejąca baza danych => istniejące klasy? Code First: Najpierw baza danych :)
riadh gomri
4
@davenewza Użyj narzędzia Entity Framework Powertools do tworzenia klas POCO z DB. Kod pierwszy do istniejącej bazy danych
Iman Mahmoudinasab
50

Najpierw baza danych i najpierw model nie ma żadnych rzeczywistych różnic. Wygenerowany kod jest taki sam i można łączyć te podejścia. Na przykład możesz utworzyć bazę danych za pomocą projektanta, niż możesz zmienić bazę danych za pomocą skryptu SQL i zaktualizować swój model.

Przy pierwszym użyciu kodu nie można zmienić modelu bez rekreacyjnej bazy danych i utraty wszystkich danych. IMHO to ograniczenie jest bardzo surowe i nie pozwala na użycie kodu w pierwszej kolejności w produkcji. Na razie nie jest to naprawdę przydatne.

Drugą niewielką wadą kodu jest to, że konstruktor modeli wymaga uprawnień do głównej bazy danych. Nie wpływa to na ciebie, jeśli korzystasz z bazy danych SQL Server Compact lub kontrolujesz serwer bazy danych.

Zaletą kodu jest przede wszystkim bardzo czysty i prosty kod. Masz pełną kontrolę nad tym kodem i możesz go łatwo modyfikować i używać go jako modelu widoku.

Mogę zalecić stosowanie pierwszego podejścia do kodu podczas tworzenia prostej autonomicznej aplikacji bez wersjonowania i używania najpierw modelu \ database w projektach wymagających modyfikacji w produkcji.

Stepan Smagin
źródło
7
Jeśli będziesz ręcznie aktualizować środowisko produkcyjne za pomocą skryptów SQL, nadal możesz zrobić to samo z Code First. Po prostu generujesz skrypty zmian, jeśli to konieczne. Kilka narzędzi może zautomatyzować te delty i możesz nadal używać Code First. Musisz tylko zmienić inicjalizator Code First na coś takiego jak CreateDatabaseIfNotExists, aby nie usuwać bieżącej bazy danych.
Esteban Brenes
Niektóre różnice dotyczą importowania widoków, a następnie ponownego generowania bazy danych, w której widoki stają się tabelami. Utrudnia wygenerowanie nowego DB i porównanie z DB prod, aby sprawdzić, czy jest zsynchronizowany.
Dave
Model First nie obsługuje funkcji SQL zdefiniowanych przez użytkownika (przynajmniej w EF4, nie wiem, czy to się zmieniło). Najpierw baza danych umożliwia importowanie plików UDF i używanie ich w zapytaniach LINQ.
Tsahi Asher
Żadnych różnic? Spróbuj zaimportować widoki i tabele SimpleMembership, a następnie wygeneruj bazę danych z modelu i zobacz, co otrzymujesz. Nawet nie blisko! Powinny one być w obie strony, ale MSFT zasadniczo porzuciło MF i DF zamiast CF, który jest również niekompletny pod względem korzystania z widoków i przechowywanych proc.
Dave
Możesz wyłączyć proces odtwarzania baz danych w oparciu o pierwsze migracje kodu i zrobić to ręcznie w modelu i bazie danych. możesz to zrobić, określając disableDatabaseInitialization = "true" w swoim web / app.config w <EntityFramework> ..... <contexts> <context type = "myNamespace.mydbContext", "myassemblyORProject" disableDatabaseInitialization = "true" /> </EntityFramework> Możesz usunąć folder migracji.
Hasteq
37

Cytując odpowiednie części z http://www.itworld.com/development/405005/3-reasons-use-code-first-design-entity-framework

3 powody, dla których warto użyć pierwszego projektu kodu w Entity Framework

1) Mniej cruft, mniej wzdęć

Użycie istniejącej bazy danych do wygenerowania pliku modelu .edmx i powiązanych modeli kodów daje gigantyczny stos automatycznie generowanego kodu. Zaleca się, aby nigdy nie dotykać tych wygenerowanych plików, aby nie uszkodzić czegoś lub zmiany nie zostaną nadpisane w następnej generacji. Kontekst i inicjator są również zablokowane w tym bałaganie. Gdy chcesz dodać funkcjonalność do wygenerowanych modeli, np. Właściwość obliczonego odczytu, musisz rozszerzyć klasę modelu. To staje się wymogiem dla prawie każdego modelu i kończy się rozszerzeniem na wszystko.

Najpierw kodem Twoje ręcznie kodowane modele stają się bazą danych. Właśnie te pliki, które budujesz, generują projekt bazy danych. Nie ma żadnych dodatkowych plików i nie ma potrzeby tworzenia rozszerzenia klasy, jeśli chcesz dodać właściwości lub cokolwiek innego, o czym baza danych nie musi wiedzieć. Możesz po prostu dodać je do tej samej klasy, pod warunkiem przestrzegania właściwej składni. Do cholery, możesz nawet wygenerować plik Model.edmx, aby zobrazować kod, jeśli chcesz.

2) Większa kontrola

Kiedy najpierw wybierasz DB, jesteś na łasce tego, co jest generowane dla twoich modeli do użycia w twojej aplikacji. Czasami konwencja nazewnictwa jest niepożądana. Czasami relacje i skojarzenia nie są dokładnie tym, czego chcesz. Innym razem niestałe relacje z leniwym ładowaniem sieją spustoszenie w odpowiedziach API.

Chociaż prawie zawsze istnieje rozwiązanie problemów z generowaniem modeli, na które możesz natknąć się, kodowanie najpierw zapewnia pełną i precyzyjną kontrolę od samego początku. Możesz kontrolować każdy aspekt zarówno modeli kodu, jak i projektu bazy danych w zaciszu własnego obiektu biznesowego. Możesz dokładnie określić relacje, ograniczenia i powiązania. Możesz jednocześnie ustawić limity znaków właściwości i rozmiary kolumn bazy danych. Możesz określić, które powiązane kolekcje mają być chętnie ładowane lub w ogóle nie być serializowane. Krótko mówiąc, jesteś odpowiedzialny za więcej rzeczy, ale masz pełną kontrolę nad projektem swojej aplikacji.

3) Kontrola wersji bazy danych

Ten jest duży. Wersjonowanie baz danych jest trudne, ale przy pierwszej migracji kodu i pierwszej migracji jest znacznie bardziej efektywna. Ponieważ schemat bazy danych jest w pełni oparty na modelach kodu, kontrolując wersję kodu źródłowego, pomagasz w wersji bazy danych. Odpowiadasz za kontrolowanie inicjalizacji kontekstu, co może pomóc ci w wykonywaniu takich czynności, jak na przykład naprawianie danych biznesowych o ustalonym ziarnie. Odpowiadasz również za tworzenie pierwszych migracji kodu.

Po pierwszym włączeniu migracji generowane są klasa konfiguracji i migracja początkowa. Początkowa migracja to Twój bieżący schemat lub podstawowa wersja 1.0. Od tego momentu dodawane będą migracje oznaczone znacznikami czasu i oznaczone deskryptorem, aby ułatwić porządkowanie wersji. Gdy wywołasz migrację dodaną z menedżera pakietów, zostanie wygenerowany nowy plik migracji zawierający wszystko, co zmieniło się w modelu kodu automatycznie zarówno w funkcji UP (), jak i DOWN (). Funkcja UP stosuje zmiany do bazy danych, funkcja DOWN usuwa te same zmiany w zdarzeniu, które chcesz wycofać. Co więcej, możesz edytować te pliki migracji, aby dodać dodatkowe zmiany, takie jak nowe widoki, indeksy, procedury składowane i cokolwiek innego. Staną się prawdziwym systemem kontroli wersji dla schematu bazy danych.

Powiedział Roohullah Allem
źródło
31

Najpierw kod wydaje się wschodzącą gwiazdą. Rzuciłem okiem na Ruby on Rails, a ich standard to najpierw kod, z migracjami baz danych.

Jeśli budujesz aplikację MVC3, uważam, że Code ma najpierw następujące zalety:

  • Łatwa dekoracja atrybutów - Możesz dekorować pola za pomocą walidacji, wymagać itp. Atrybutów, jest to dość niewygodne z modelowaniem EF
  • Żadnych dziwnych błędów modelowania - Modelowanie EF często zawiera dziwne błędy, na przykład gdy próbujesz zmienić nazwę właściwości asocjacji, musi ona pasować do bazowych metadanych - bardzo mało elastyczna.
  • Nie jest niewygodne do scalania - Podczas korzystania z narzędzi kontroli wersji kodu, takich jak mercurial, scalanie plików .edmx jest uciążliwe. Jesteś programistą przyzwyczajonym do C # i tam scalasz .edmx. Nie w przypadku kodu pierwszego.
  • Kontrast z powrotem najpierw do kodu, a masz pełną kontrolę bez wszystkich ukrytych zawiłości i nieznanych problemów.
  • Zalecam korzystanie z narzędzia wiersza polecenia Menedżera pakietów, nawet nie używaj narzędzi graficznych do dodawania nowego kontrolera do widoków rusztowania.
  • DB-Migrations - Następnie możesz również włączyć migracje. To jest tak potężne. Wprowadzasz zmiany w swoim modelu w kodzie, a następnie środowisko może śledzić zmiany schematu, dzięki czemu możesz bezproblemowo wdrażać aktualizacje, a wersje schematu są automatycznie uaktualniane (aw razie potrzeby obniżane). (Nie jestem pewien, ale prawdopodobnie działa to również w przypadku pierwszego modelu)

Aktualizacja

Pytanie dotyczy także porównania kodu-pierwszego do modelu EDMX / db-first. Kod-pierwszy może być również użyty w obu tych podejściach:

Todd
źródło
3
Najpierw model nie koduje najpierw POCO, to jest Code First, Model-First to Visual Designer do automatycznego generowania POCO, a następnie generowania baz danych z modelu.
Diego Mendes
Obecnie zarówno na ścieżce wizualnej, jak i kodowej, możesz najpierw wykonać „Model” lub „Baza danych”. Pierwszym z nich jest ręczne projektowanie (za pomocą edytora kodu lub wizualnego), drugim budowanie bazy danych i tworzenie modelu (POCO lub EDMX).
Todd
11

Najpierw używam bazy danych EF, aby zapewnić większą elastyczność i kontrolę nad konfiguracją bazy danych.

Najpierw kod EF i model wydawały się na pierwszy rzut oka fajne i zapewniają niezależność bazy danych, jednak w ten sposób nie można określić, co uważam za bardzo podstawowe i typowe informacje o konfiguracji bazy danych. Na przykład indeksy tabel, metadane zabezpieczeń lub klucz podstawowy zawierający więcej niż jedną kolumnę. Uważam, że chcę korzystać z tych i innych typowych funkcji bazy danych, dlatego i tak muszę przeprowadzić konfigurację bazy danych bezpośrednio.

Uważam, że domyślne klasy POCO generowane podczas DB są najpierw bardzo czyste, jednak brakuje im bardzo użytecznych atrybutów adnotacji danych lub mapowań do procedur przechowywanych. Użyłem szablonów T4, aby pokonać niektóre z tych ograniczeń. Szablony T4 są niesamowite, zwłaszcza w połączeniu z własnymi metadanymi i częściowymi klasami.

Najpierw model wydaje się mieć duży potencjał, ale daje mi wiele błędów podczas refaktoryzacji złożonego schematu bazy danych. Nie pewny dlaczego.

użytkownik1618371
źródło
4
Ty można zdefiniować klucze złożone najpierw za pomocą kodu - stackoverflow.com/questions/5466374/...
Jakub Konecki
3
W przypadku przyszłych czytelników nie jest to już możliwe, możesz najpierw dodać indeksy, wielokolumnowe klucze podstawowe i tego rodzaju rzeczy w kodzie EF.
tobiak777
1
EF powinien był zostać naprawiony, aby wszystkie 3 podejścia mogły być stosowane zamiennie w tej samej bazie danych, ponieważ istnieją zalety i wady wszystkich 3 podejść
Dave
Dodatkowo prawda o niezbyt idealnym rozwiązaniu w postaci kodu Najpierw używam bazy danych ze względu na migrację do innego IDE / języka w przyszłości i chcę mieć solidną i zintegrowaną strukturę bazy danych, innym faktem, który wolę najpierw, jest elastyczność w zmianie dowolnej części przechowywanie danych.
QMaster,
7

Praca z dużymi modelami była bardzo powolna przed SP1, (nie wypróbowałem go po SP1, ale mówi się, że jest to teraz snap).

Nadal najpierw projektuję swoje tabele, a następnie wbudowane narzędzie generuje dla mnie POCO, więc wykonanie każdego zadania poco wymaga wykonywania powtarzalnych zadań.

kiedy używasz systemów kontroli źródła, możesz łatwo śledzić historię swoich POCO, nie jest to takie proste z kodem generowanym przez projektanta.

Mam bazę dla mojego POCO, co sprawia, że ​​wiele rzeczy jest całkiem łatwych.

Mam widoki dla wszystkich moich tabel, każdy widok podstawowy zawiera podstawowe informacje o moich kluczach obcych, a moje widoki POCO pochodzą z moich klas POCO, co jest znowu całkiem przydatne.

I wreszcie nie lubię projektantów.

hazimdikenli
źródło
8
„gdy używasz systemów kontroli źródła, możesz łatwo śledzić historię swoich POCO, nie jest to takie proste z kodem generowanym przez projektantów”. - Trzymam kod generowany przez projektantów w Kontroli źródła, więc zawsze mogę przeglądać historię.
Jakub Konecki
1
@JakubKonecki Czy kiedykolwiek próbowałeś scalić pliki EDMX w zespole ponad 3 osób? To tylko ból ... Zamiast tego ludzie starają się uniknąć scalania i po prostu biorą drugą wersję i powtarzają własne zmiany, ponieważ scalanie jest podatne na niepowodzenie w pliku generowanym automatycznie z tysiącami wierszy XML.
bytecode77
6

Przykład pierwszego podejścia do bazy danych:

Bez pisania kodu: ASP.NET MVC / MVC3 Baza danych Pierwsze podejście / Baza danych pierwsza

I myślę, że jest to lepsze niż inne podejścia, ponieważ utrata danych jest mniejsza przy tym podejściu.

AukI
źródło
Czy możesz rozwinąć kwestię „mniejszej utraty danych” przy pierwszym podejściu do DB? Jak przeprowadziłbyś transformację danych, gdybyś podzielił istniejącą tabelę na dwie części?
Jakub Konecki
prawdopodobnie skończyłbyś pisać skryptem SQL, który zajmuje się transformacją. Ogólnie rzecz biorąc, MS ogłosiło, że usprawni migrację danych Code First dzięki swojej nowej wersji, więc może to nie być argumentem w przyszłości.
ckonig
Problem z bazą danych przede wszystkim polega na tym, że projekt bazy danych ma generalnie wadliwe abstrakcje, które przeciekają do twojego modelu ... tabele połączeń itp. Zadaniem bazy danych jest po prostu utrzymanie modelu.
Nerdfest,
Ta „odpowiedź” jest opinią opartą na braku argumentów, jedno zdanie nie stanowi stanowiska.
TravisO,
Czy możesz rozwinąć kwestię „mniejszej utraty danych” przy pierwszym podejściu do DB?
amal50
4

IMHO Myślę, że wszystkie modele mają świetne miejsce, ale problem, jaki mam z pierwszym podejściem do modelu, występuje w wielu dużych firmach, w których DBA kontroluje bazy danych. Nie można elastycznie budować aplikacji bez pierwszego podejścia do baz danych. Pracowałem nad wieloma projektami, a jeśli chodzi o wdrożenie, chcieli mieć pełną kontrolę.

O ile zgadzam się ze wszystkimi możliwymi odmianami Kod po pierwsze, model po pierwsze, baza danych po pierwsze, musisz wziąć pod uwagę rzeczywiste środowisko produkcyjne. Więc jeśli twój system będzie dużą aplikacją bazową dla wielu użytkowników, a DBA uruchomi program, możesz rozważyć pierwszą opcję bazy danych tylko moją opinię.

Matthew Parton
źródło
Masz rację. MS dało programistom różne podejścia, ponieważ są to różne scenariusze. Powinieneś wiedzieć wszystko i decydować na podstawie scenariusza, co jest najlepsze dla projektu, a następnie co najbardziej lubisz.
Sterling Diaz
0

Myślę, że jedną z zalet kodu jest to, że możesz wykonać kopię zapasową wszystkich zmian dokonanych w systemie kontroli wersji, takim jak Git. Ponieważ wszystkie tabele i relacje są przechowywane w zasadniczo klasach, możesz cofnąć się w czasie i zobaczyć, jaka była wcześniej struktura bazy danych.

anonimowy_dojo
źródło