Czy uważa się za anty-wzorzec kodowania kodu SQL w aplikacji takiej jak ta:
public List<int> getPersonIDs()
{
List<int> listPersonIDs = new List<int>();
using (SqlConnection connection = new SqlConnection(
ConfigurationManager.ConnectionStrings["Connection"].ConnectionString))
using (SqlCommand command = new SqlCommand())
{
command.CommandText = "select id from Person";
command.Connection = connection;
connection.Open();
SqlDataReader datareader = command.ExecuteReader();
while (datareader.Read())
{
listPersonIDs.Add(Convert.ToInt32(datareader["ID"]));
}
}
return listPersonIDs;
}
Normalnie miałbym warstwę repozytorium itp., Ale dla uproszczenia wykluczyłem ją z powyższego kodu.
Niedawno otrzymałem informację zwrotną od kolegi, który skarżył się, że SQL został napisany w kodzie źródłowym. Nie miałem okazji zapytać, dlaczego, a teraz go nie ma przez dwa tygodnie (może dłużej). Zakładam, że miał na myśli albo:
- Użyj LINQ
lub - Użyj procedur przechowywanych dla SQL
Mam rację? Czy uważa się, że zapisywanie kodu SQL w kodzie źródłowym jest anty-wzorcem? Jesteśmy małym zespołem pracującym nad tym projektem. Myślę, że zaletą procedur przechowywanych jest to, że programiści SQL mogą zaangażować się w proces programowania (pisanie procedur przechowywanych itp.).
Edytuj Poniższy link mówi o zakodowanych instrukcjach SQL: https://docs.microsoft.com/en-us/sql/odbc/reference/develop-app/hard-coded-sql-statements . Czy jest jakaś korzyść z przygotowania instrukcji SQL?
Odpowiedzi:
Wyłączyłeś kluczową część dla uproszczenia. Repozytorium jest warstwą abstrakcji dla trwałości. Wydzielamy uporczywość na jej własną warstwę, abyśmy mogli łatwiej zmieniać technologię utrwalania , kiedy jest taka potrzeba. Dlatego posiadanie SQL poza warstwą trwałości całkowicie ogranicza wysiłek posiadania oddzielnej warstwy trwałości.
W rezultacie: SQL jest w porządku w warstwie trwałości, która jest specyficzna dla technologii SQL (np. SQL jest w porządku,
SQLCustomerRepository
ale nie w aMongoCustomerRepository
). Poza warstwą trwałości SQL łamie twoją abstrakcję i dlatego jest uważane przeze mnie za bardzo złą praktykę .Jeśli chodzi o narzędzia takie jak LINQ lub JPQL: mogą one jedynie wyodrębnić smaki SQL. Posiadanie zapytań o kod LINQ lub JPQL poza repozytorium przerywa abstrakcję trwałości tak samo jak surowy SQL.
Kolejną ogromną zaletą oddzielnej warstwy trwałości jest to, że pozwala ona na unittestowanie kodu logiki biznesowej bez konieczności konfigurowania serwera DB.
Otrzymujesz szybki profil jednostki z niskim profilem pamięci i powtarzalnymi wynikami na wszystkich platformach obsługiwanych przez Twój język.
W architekturze usługi MVC + jest to proste zadanie wyśmiewania instancji repozytorium, tworzenia pewnych fałszywych danych w pamięci i określania, że repozytorium powinno zwracać te fałszywe dane, gdy wywoływany jest określony moduł pobierający. Następnie możesz zdefiniować dane testowe według najcichszych i nie martw się o późniejsze wyczyszczenie bazy danych.
Testowanie zapisów w bazie danych jest tak proste: sprawdź, czy zostały wywołane odpowiednie metody aktualizacji w warstwie trwałości, i zapewnij, że jednostki były w odpowiednim stanie, kiedy to się stało.
źródło
Obecnie większość standardowych aplikacji biznesowych wykorzystuje różne warstwy z różnymi obowiązkami. Jednak jakie warstwy używasz w swojej aplikacji i która warstwa odpowiada za Ciebie i twój zespół. Zanim podejmiesz decyzję, czy umieszczenie SQL bezpośrednio w funkcji, którą nam pokazałeś, jest właściwe, czy złe, musisz wiedzieć
która warstwa w Twojej aplikacji ma jaką odpowiedzialność
z której warstwy pochodzi powyższa funkcja
Nie ma na to rozwiązania „uniwersalnego”. W niektórych aplikacjach projektanci wolą używać frameworku ORM i pozwolić, aby frameworki wygenerowały cały SQL. W niektórych aplikacjach projektanci wolą przechowywać taki SQL wyłącznie w procedurach przechowywanych. W przypadku niektórych aplikacji istnieje odręcznie zapisywana warstwa trwałości (lub repozytorium), w której żyje SQL, a w przypadku innych aplikacji można w określonych okolicznościach zdefiniować wyjątki od ścisłego umieszczenia SQL w tej warstwie trwałości.
Więc o czym musisz pomyśleć: jakie warstwy chcesz lub potrzebujesz w konkretnej aplikacji i jak chcesz mieć obowiązki? Napisałeś „Normalnie miałbym warstwę repozytorium” , ale jakie dokładnie obowiązki chcesz mieć w tej warstwie i jakie obowiązki chcesz nałożyć gdzie indziej? Odpowiedz najpierw, a potem sam możesz odpowiedzieć na swoje pytanie.
źródło
Marstato daje dobrą odpowiedź, ale chciałbym dodać więcej komentarzy.
SQL w źródle NIE jest anty-wzorcem, ale może powodować problemy. Pamiętam, kiedy musiałeś wstawiać zapytania SQL we właściwościach składników upuszczanych na każdą formę. To sprawiło, że wszystko było naprawdę brzydkie, naprawdę szybkie i trzeba było skakać przez obręcze, aby znaleźć zapytania. Stałem się silnym zwolennikiem scentralizowania dostępu do bazy danych w jak największym stopniu w ramach ograniczeń języków, z którymi pracowałem. Twój kolega może mieć retrospekcje do tych mrocznych dni.
Teraz niektóre komentarze mówią o zablokowaniu dostawcy, jakby to automatycznie było czymś złym. To nie jest Jeśli mam podpisania czek sześć postać każdego roku korzystać z Oracle, można założyć, że chcę żadnej aplikacji z dostępem do bazy danych za pomocą dodatkowej składni Oracle odpowiednioale w pełni. Nie będę szczęśliwy, jeśli moja błyszcząca baza danych zostanie sparaliżowana przez programistów piszących waniliowo ANSI SQL, gdy istnieje „sposób Oracle” na pisanie SQL, który nie kaleczy bazy danych. Tak, zmiana baz danych będzie trudniejsza, ale widziałem to tylko w witrynie dużego klienta kilka razy w ciągu ponad 20 lat, a jedna z tych spraw przenosiła się z bazy danych DB2 -> Oracle, ponieważ komputer mainframe, na którym przechowywano bazę danych DB2, był przestarzały i został wycofany z eksploatacji . Tak, to jest blokada dostawcy, ale dla klientów korporacyjnych pożądane jest opłacenie drogiego, wydajnego RDBMS, takiego jak Oracle lub Microsoft SQL Server, a następnie wykorzystanie go w jak największym stopniu. Jako kocyk komfortowy masz umowę wsparcia. Jeśli płacę za bazę danych z bogatą implementacją procedury składowanej,
To prowadzi do następnego punktu: jeśli piszesz aplikację, która uzyskuje dostęp do bazy danych SQL , musisz nauczyć się języka SQL, a także innego języka, a przez naukę rozumiem również optymalizację zapytań; Zdenerwuję się na tobie, jeśli napiszesz kod generujący SQL, który opróżnia pamięć podręczną SQL zaporą prawie identycznych zapytań, gdy mógłbyś użyć jednego sprytnie sparametryzowanego zapytania.
Bez wymówek, bez chowania się za ścianą Hibernacji. Źle używane ORM mogą naprawdę osłabić wydajność aplikacji. Pamiętam kilka lat temu pytanie na temat Przepełnienia stosu:
Co powiesz na „UPDATE table SET field1 = gdzie field2 ma wartość True, a Field3> 100”. Problemem może być tworzenie i usuwanie 250 000 obiektów ...
tzn. zignoruj Hibernację, gdy nie jest właściwe jego użycie. Zrozumieć bazę danych.
Podsumowując, osadzanie SQL w kodzie może być złą praktyką, ale są znacznie gorsze rzeczy, które możesz zrobić, próbując uniknąć osadzania SQL.
źródło
Tak, stałe kodowanie ciągów SQL w kodzie aplikacji jest ogólnie anty-wzorcem.
Spróbujmy odłożyć na bok tolerancję, którą wypracowaliśmy od lat postrzegania tego w kodzie produkcyjnym. Mieszanie całkowicie różnych języków z różną składnią w tym samym pliku nie jest na ogół pożądaną techniką programowania. Różni się to od języków szablonów, takich jak Razor, które mają nadawać kontekstowe znaczenie wielu językach. Jak wspomina Sava B. w komentarzu poniżej, SQL w twoim C # lub innym języku aplikacji (Python, C ++ itp.) Jest ciągiem jak każdy inny i jest semantycznie bez znaczenia. To samo dotyczy w większości przypadków mieszania więcej niż jednego języka, choć oczywiście są sytuacje, w których jest to dopuszczalne, takie jak wbudowanie w C, małe i zrozumiałe fragmenty CSS w HTML (zauważ, że CSS jest zaprojektowany do mieszania z HTML ), i inni.
(Robert C. Martin o mieszaniu języków, Clean Code , rozdział 17, „Zapachy i heurystyka kodu”, strona 288)
Dla tej odpowiedzi skupię się na SQL (jak zadano w pytaniu). Podczas przechowywania SQL jako zestawu oddzielonych ciągów mogą wystąpić następujące problemy:
@
Prefiks C # ułatwia to, ale widziałem dużo kodu, który cytuje każdą linię SQL i unika znaku nowej linii."SELECT col1, col2...colN"\ "FROM painfulExample"\ "WHERE maintainability IS NULL"\ "AND modification.effort > @necessary"\
Pełne ORM (obiekty mapujące obiektowo-relacyjne, takie jak Entity Framework lub Hibernacja) mogą wyeliminować losowo zaszyty SQL w kodzie aplikacji. Moje użycie SQL i plików zasobów jest tylko przykładem. ORM, klasy pomocnicze itp. Mogą pomóc w osiągnięciu celu czyszczenia kodu.
Jak Kevin powiedział we wcześniejszej odpowiedzi, kod SQL może być akceptowalny w małych projektach, ale duże projekty zaczynają się jako małe projekty, a prawdopodobieństwo, że większość zespołów wróci i zrobi to poprawnie, jest często odwrotnie proporcjonalne do rozmiaru kodu.
Istnieje wiele prostych sposobów utrzymywania SQL w projekcie. Jedną z metod, których często używam, jest umieszczenie każdej instrukcji SQL w pliku zasobów Visual Studio, zwykle o nazwie „sql”. Plik tekstowy, dokument JSON lub inne źródło danych może być uzasadnione w zależności od narzędzi. W niektórych przypadkach najlepszą opcją może być osobna klasa poświęcona tworzeniu łańcuchów SQL, ale może ona zawierać niektóre z wyżej opisanych problemów.
Przykład SQL: Który wygląda bardziej elegancko ?:
Staje się
SQL zawsze znajduje się w łatwym do zlokalizowania pliku lub zgrupowanym zestawie plików, każdy z opisową nazwą, która opisuje, co robi, a nie jak to robi, każdy z miejscem na komentarz, który nie zakłóci przepływu kodu aplikacji :
Ta prosta metoda wykonuje pojedyncze zapytanie. Z mojego doświadczenia wynika, że korzyści są skalowane, ponieważ użycie „języka obcego” staje się coraz bardziej wyrafinowane. Moje użycie pliku zasobów jest tylko przykładem. Różne metody mogą być bardziej odpowiednie w zależności od języka (w tym przypadku SQL) i platformy.
Ta i inne metody rozwiązują powyższą listę w następujący sposób:
SQL
.return SqlResource.DoTheThing;
To prawda, że te implementacje mogą pomijać zasób i zawierać SQL w ciągu, ale niektóre (nie wszystkie) problemy powyżej nadal będą się pojawiać.sql.GetOrdersForAccount
Zamiast bardziej rozwartychSELECT ... FROM ... WHERE...
Tworzenie SQL w zasobie jest szybkie, więc nie ma większego impulsu do mieszania wykorzystania zasobów z SQL-in-code.
Niezależnie od wybranej metody odkryłem, że mieszanie języków zwykle obniża jakość kodu. Mam nadzieję, że niektóre opisane tutaj problemy i rozwiązania pomogą deweloperom wyeliminować ten zapach kodu, gdy jest to właściwe.
źródło
To zależy. Istnieje wiele różnych podejść, które mogą działać:
Jak to często bywa, jeśli twój projekt wybrał już jedną z tych technik, powinieneś być spójny z resztą projektu.
(1) i (3) są względnie dobre w utrzymywaniu niezależności między logiką aplikacji a bazą danych, w tym sensie, że aplikacja będzie kontynuować kompilację i przejść podstawowe testy dymu, jeśli zastąpisz bazę danych innym dostawcą. Jednak większość dostawców nie jest w pełni zgodna ze standardem SQL, więc zastąpienie dowolnego dostawcy innym dostawcą będzie prawdopodobnie wymagało obszernych testów i wykrywania błędów, niezależnie od używanej techniki. Jestem sceptycznie nastawiony do tego, że jest to tak wielka sprawa, jak się wydaje. Zmiana baz danych jest w zasadzie ostatecznością, gdy nie możesz uzyskać bieżącej bazy danych, która zaspokoi Twoje potrzeby. Jeśli tak się stanie, prawdopodobnie źle wybrałeś bazę danych.
Wybór między (1) i (3) zależy głównie od tego, jak bardzo lubisz ORM. Moim zdaniem są one nadużywane. Stanowią słabą reprezentację relacyjnego modelu danych, ponieważ wiersze nie mają tożsamości w sposób, w jaki obiekty mają tożsamość. Prawdopodobnie napotkasz punkty bólu wokół unikalnych ograniczeń, połączeń i możesz mieć trudności z wyrażaniem bardziej skomplikowanych zapytań w zależności od mocy ORM. Z drugiej strony (1) prawdopodobnie będzie wymagał znacznie więcej kodu niż ORM.
(2) według mojego doświadczenia jest rzadko spotykany. Problem polega na tym, że wiele sklepów zabrania SWE bezpośredniego modyfikowania schematu bazy danych (ponieważ „takie jest zadanie DBA”). To niekoniecznie jest samo w sobie Złe; zmiany schematu mają znaczny potencjał do niszczenia rzeczy i mogą wymagać ostrożnego wdrożenia. Jednak aby (2) działało, SWE powinny przynajmniej móc wprowadzać nowe widoki i modyfikować zapytania pomocnicze istniejących widoków przy minimalnej biurokracji lub bez biurokracji. Jeśli tak nie jest w twoim miejscu pracy, (2) prawdopodobnie nie będzie dla ciebie pracował.
Z drugiej strony, jeśli możesz sprawić, że (2) zadziała, jest to znacznie lepsze niż większość innych rozwiązań, ponieważ utrzymuje logikę relacyjną w SQL zamiast kodu aplikacji. W przeciwieństwie do języków programowania ogólnego przeznaczenia, SQL jest specjalnie zaprojektowany dla relacyjnego modelu danych i odpowiednio lepiej wyraża skomplikowane zapytania i transformacje danych. Widoki można również przenosić wraz z resztą schematu podczas zmiany baz danych, ale utrudniają one takie ruchy.
W przypadku odczytów procedury składowane są w zasadzie po prostu gorszą wersją (2). Nie polecam ich w tym zakresie, ale nadal możesz chcieć ich do zapisu, jeśli twoja baza danych nie obsługuje widoków , które można aktualizować , lub jeśli musisz zrobić coś bardziej złożonego niż wstawianie lub aktualizowanie pojedynczego wiersza na raz (np. transakcje, odczyt, zapis itp.). Możesz połączyć procedurę składowaną z widokiem za pomocą wyzwalacza (tj
CREATE TRIGGER trigger_name INSTEAD OF INSERT ON view_name FOR EACH ROW EXECUTE PROCEDURE procedure_name;
), ale opinie różnią się znacznie co do tego, czy jest to rzeczywiście dobry pomysł. Zwolennicy powiedzą ci, że utrzymuje SQL, że twoja aplikacja wykonuje się tak prosto, jak to możliwe. Krytycy powiedzą ci, że jest to niedopuszczalny poziom „magii” i że powinieneś po prostu wykonać procedurę bezpośrednio z aplikacji. Powiedziałbym, że jest to lepszy pomysł, jeśli procedura składowana wygląda lub działa dużo jak uINSERT
,UPDATE
alboDELETE
i gorzej pomysł, nawet jeśli robi coś innego. Ostatecznie musisz sam zdecydować, który styl ma większy sens.(4) jest nierozwiązaniem. Może się to przydać w przypadku małych projektów lub dużych, które sporadycznie wchodzą w interakcje z bazą danych. Ale w przypadku projektów z dużą ilością SQL nie jest to dobry pomysł, ponieważ możesz mieć przypadkowe duplikaty lub odmiany tego samego zapytania rozrzucone wokół aplikacji, co zakłóca czytelność i refaktoryzację.
źródło
Niekoniecznie. Jeśli przeczytasz tutaj wszystkie komentarze, w kodzie źródłowym znajdziesz prawidłowe argumenty dla zakodowanych na stałe instrukcji SQL.
Problem dotyczy miejsca, w którym umieszczasz wyciągi . Jeśli umieścisz instrukcje SQL w całym projekcie, prawdopodobnie zignorujesz niektóre zasady SOLID, których zwykle staramy się przestrzegać.
Nie możemy powiedzieć, co miał na myśli. Możemy jednak zgadywać. Na przykład pierwszy, jaki przychodzi mi do głowy, to blokada dostawcy . Twarde kodowanie instrukcji SQL może doprowadzić do ścisłego powiązania aplikacji z silnikiem DB. Na przykład przy użyciu określonych funkcji dostawcy, które nie są zgodne z ANSI.
To niekoniecznie jest złe lub złe. Po prostu wskazuję na fakt.
Ignorowanie zasad SOLID i blokad dostawcy może mieć negatywne konsekwencje, które możesz ignorować. Dlatego zazwyczaj dobrze jest siedzieć z zespołem i ujawniać swoje wątpliwości.
Myślę, że nie ma to nic wspólnego z zaletami procedur przechowywanych. Co więcej, jeśli twój kolega nie lubi zakodowanego SQL, prawdopodobnie przeniesienie firmy do procedur przechowywanych również go nie polubi.
Tak. Post zawiera zalety przygotowanych wypowiedzi . To rodzaj szablonów SQL. Bardziej bezpieczne niż konkatenacja łańcuchów. Ale post nie zachęca cię do pójścia tą drogą ani nie potwierdza, że masz rację. Wyjaśnia tylko, w jaki sposób możemy używać zakodowanego SQL w bezpieczny i wydajny sposób.
Podsumowując, najpierw spróbuj spytać kolegę. Wyślij e-mail, zadzwoń do niego ... Niezależnie od tego, czy odpowie, czy nie, usiądź z zespołem i ujawnij swoje wątpliwości. Znajdź rozwiązanie, które najlepiej odpowiada Twoim wymaganiom. Nie rób fałszywych założeń na podstawie tego, co tam czytasz.
źródło
select GETDATE(), ....
GETDATE () to funkcja daty SqlServer. W innych silnikach funkcja ma inną nazwę, inne wyrażenie ...Tak, myślę, że to zła praktyka. Inni wskazywali na zalety przechowywania całego kodu dostępu do danych we własnej warstwie. Nie musisz go szukać, łatwiej jest go zoptymalizować i przetestować ... Ale nawet w tej warstwie masz kilka możliwości: użyj ORM, użyj sproców lub osadzić zapytania SQL jako ciągi znaków. Powiedziałbym, że ciągi zapytań SQL są zdecydowanie najgorszą opcją.
Dzięki ORM programowanie staje się znacznie łatwiejsze i mniej podatne na błędy. Dzięki EF definiujesz swój schemat po prostu tworząc klasy modelu (i tak musiałbyś je utworzyć). Wysyłanie zapytań za pomocą LINQ to pestka - często unikasz 2 linii c #, w których inaczej musiałbyś pisać i utrzymywać sproc. IMO ma to ogromną zaletę, jeśli chodzi o produktywność i łatwość konserwacji - mniej kodu, mniej problemów. Ale jest narzut związany z wydajnością, nawet jeśli wiesz, co robisz.
Sproc (lub funkcje) to druga opcja. Tutaj piszesz zapytania SQL ręcznie. Ale przynajmniej masz gwarancję, że są poprawne. Jeśli pracujesz w .NET, Visual Studio wyrzuci nawet błędy kompilatora, jeśli SQL jest nieprawidłowy. To jest świetne. Jeśli zmienisz lub usuniesz część kolumn, a niektóre zapytania staną się nieprawidłowe, przynajmniej prawdopodobnie dowiesz się o tym podczas kompilacji. Znacznie łatwiej jest także utrzymywać sproki we własnych plikach - prawdopodobnie dostaniesz podświetlanie składni, autouzupełnianie ... itd.
Jeśli Twoje zapytania są przechowywane jako sproki, możesz je również zmienić bez ponownej kompilacji i ponownego wdrożenia aplikacji. Jeśli zauważysz, że coś w twoim SQL jest zepsute, DBA może to naprawić bez potrzeby dostępu do kodu aplikacji. Ogólnie rzecz biorąc, jeśli twoje zapytania są w literałach łańcuchowych, dbas nie może wykonać swojej pracy prawie tak łatwo.
Zapytania SQL jako ciągi literalne sprawią, że twój dostęp do kodu c # będzie mniej czytelny.
Zasadniczo magiczne stałe są złe. Dotyczy to literałów łańcuchowych.
źródło
Nie jest to anty-wzór (odpowiedź ta jest niebezpiecznie bliska opinii). Ale formatowanie kodu jest ważne, a ciąg SQL powinien być sformatowany, aby był wyraźnie oddzielony od kodu, który go używa. Na przykład
źródło
Nie mogę ci powiedzieć, co miał na myśli twój kolega. Ale mogę odpowiedzieć na to:
TAK . Używanie przygotowanych instrukcji ze zmiennymi powiązanymi jest zalecaną ochroną przed wstrzykiwaniem SQL , który pozostaje największym zagrożeniem bezpieczeństwa dla aplikacji internetowych od ponad dekady . Ten atak jest tak powszechny, że pojawiał się w komiksach internetowych prawie dziesięć lat temu, i nadszedł najwyższy czas, aby wdrożyć skuteczne zabezpieczenia.
... a najskuteczniejszą obroną przed złym połączeniem ciągów zapytań nie jest przede wszystkim reprezentowanie zapytań jako ciągów, ale użycie bezpiecznego API typu zapytań do tworzenia zapytań. Na przykład oto, jak napisałbym zapytanie w Javie przy użyciu QueryDSL:
Jak widać, nie ma tu żadnego dosłownego ciągu, co sprawia, że wstrzyknięcie SQL jest prawie niemożliwe. Co więcej, miałem napisane uzupełnienie kodu i moje IDE może refaktoryzować to, czy kiedykolwiek zmienię nazwę kolumny id. Ponadto mogę łatwo znaleźć wszystkie zapytania dotyczące tabeli osób, pytając moje IDE, gdzie
person
zmienna jest dostępna. Aha, czy zauważyłeś, że jest trochę krótszy i łatwiejszy dla oczu niż twój kod?Mogę tylko założyć, że coś takiego jest dostępne również dla C #. Na przykład słyszę świetne rzeczy o LINQ.
Podsumowując, reprezentowanie zapytań jako ciągów SQL utrudnia IDE znaczącą pomoc w pisaniu i refaktoryzacji zapytań, odracza wykrywanie błędów składni i typów od czasu kompilacji do czasu wykonania, a także przyczynia się do powstawania luk w iniekcji SQL [1]. Tak, istnieją ważne powody, dla których można nie chcieć ciągów SQL w kodzie źródłowym.
[1]: Tak, prawidłowe użycie przygotowanych instrukcji zapobiega także wstrzykiwaniu SQL. Ale ta inna odpowiedź w tym wątku była podatna na wstrzyknięcie SQL, dopóki komentator tego nie zauważył, nie budzi zaufania do młodszych programistów, którzy używają ich poprawnie w razie potrzeby ...
źródło
Wiele świetnych odpowiedzi tutaj. Oprócz tego, co już powiedziano, chciałbym dodać jeszcze jedną rzecz.
Nie uważam używania wbudowanego SQL za anty-wzorzec. To, co uważam za anty-wzór, to każdy programista robiąc swoje. Jako zespół musisz zdecydować się na wspólny standard. Jeśli wszyscy używają linq, wtedy używasz linq, jeśli wszyscy używają widoków i procedur przechowywanych, robisz to.
Zawsze jednak miej otwarty umysł i nie daj się zwieść dogmatom. Jeśli twój sklep jest sklepem „linq”, korzystasz z niego. Z wyjątkiem tego jednego miejsca, w którym linq absolutnie nie działa. (Ale nie powinieneś 99,9% czasu).
Chciałbym więc zbadać kod w bazie kodu i sprawdzić, jak pracują twoi koledzy.
źródło
Kod wygląda jak z warstwy interakcji z bazą danych, która znajduje się między bazą danych a resztą kodu. Jeśli tak, to nie jest to anty-wzór.
Ta metoda jest częścią warstwy, nawet jeśli OP myśli inaczej (zwykły dostęp do bazy danych, brak mieszania z czymkolwiek innym). Być może jest źle umieszczony w kodzie. Ta metoda należy do osobnej klasy „warstwy interfejsu bazy danych”. Byłoby anty-wzorcem umieszczanie go w zwykłej klasie obok metod realizujących działania inne niż bazy danych.
Anty-wzorzec polegałby na wywołaniu SQL z innego losowego miejsca w kodzie. Musisz zdefiniować warstwę między bazą danych a resztą kodu, ale nie jest tak, że musisz bezwzględnie użyć popularnego narzędzia, które może ci w tym pomóc.
źródło
Moim zdaniem nie ma anty-wzorca, ale będziesz miał do czynienia z odstępami formatowania łańcucha, szczególnie w przypadku dużych zapytań, które nie mieszczą się w jednej linii.
kolejną zaletą jest to, że staje się znacznie trudniejsze w przypadku dynamicznych zapytań, które powinny być budowane zgodnie z określonymi warunkami.
Sugeruję użycie narzędzia do tworzenia zapytań SQL
źródło
W przypadku wielu nowoczesnych organizacji z potokami szybkiego wdrażania, w których zmiany kodu mogą być kompilowane, testowane i przekazywane do produkcji w ciągu kilku minut, całkowicie sensowne jest osadzanie instrukcji SQL w kodzie aplikacji. To niekoniecznie jest anty-wzór w zależności od tego, jak sobie z tym poradzisz.
Prawidłowy przypadek zastosowania obecnie procedur przechowywanych dotyczy organizacji, w których istnieje wiele procesów związanych z wdrożeniami produkcyjnymi, które mogą obejmować tygodnie cykli kontroli jakości itp. W tym scenariuszu zespół DBA może rozwiązać problemy z wydajnością pojawiające się dopiero po początkowym wdrożeniu produkcyjnym poprzez optymalizację zapytania w procedurach przechowywanych.
Jeśli nie jesteś w takiej sytuacji, zalecamy osadzenie kodu SQL w kodzie aplikacji. Przeczytaj inne odpowiedzi w tym wątku, aby uzyskać porady na temat tego, jak to zrobić.
Oryginalny tekst poniżej dla kontekstu
Główną zaletą procedur przechowywanych jest to, że można zoptymalizować wydajność bazy danych bez ponownej kompilacji i ponownego wdrażania aplikacji.
W wielu organizacjach kod może zostać przekazany do produkcji dopiero po cyklu kontroli jakości itp., Co może potrwać kilka dni lub tygodni. Jeśli w Twoim systemie wystąpi problem z wydajnością bazy danych z powodu zmiany wzorców użytkowania lub zwiększenia rozmiarów tabel itp., Może być dość trudne do wyśledzenia problemu z zakodowanymi zapytaniami, podczas gdy baza danych będzie zawierała narzędzia / raporty itp., Które zidentyfikują problematyczne procedury przechowywane . Dzięki procedurom przechowywanym rozwiązania mogą być testowane / testowane w produkcji, a problem może zostać szybko rozwiązany bez konieczności wypychania nowej wersji oprogramowania aplikacji.
Jeśli ten problem nie jest ważny w twoim systemie, to jest to całkowicie poprawna decyzja, aby na stałe zapisać instrukcje SQL w aplikacji.
źródło