Połączenie z bazą dwóch aplikacji oraz sens ORM

1

Witam, nie wiem czy nie powinienem tego napisać w Newbie, w razie potrzeby proszę o przeniesienie.

Piszę pracę inżynierską i zdecydowałem się napisać to w C#. W Javie piszę o początku studiów, stwierdziłem, że spróbuję .NET. Chcę napisać dwie aplikacje, jedna WPF, druga ASP NET MVC. Strona ASP będzie korzystała z danych generowanych i modofyikowanych w programie WPF, a także sama będzie mogła generować nowe dane, z których z kolei będzie korzystać aplikacja WPF. Generalnie chodzi mi o to, jak to połączyć. Silnik bazy to MSSQL. Myślałem nad dwoma bazami danych, jedna lokalnie w powiedzmy docelowej firmie, gdzie będzie na stanowiskach aplikacja WPF, a druga z tej głównej na serwerze www. Obie bazy zlinkowane. Na obu triggery, które wykonują odpowiednie operację na zdalnej bazie. Druga opcja to jedna baza. Dostęp z aplikacji www do danych przez webservice z aplikacji na serwerze, czyli dojdzie kolejna aplikacja. Może są jakieś inne opcje?

Drugie pytanie to ORM, w ogóle sens jego użycia. Zastanawiam się nad użyciem EF, ewentualnie samemu napisać repozytoria. Moje wątpliwości co do wykorzystania to m.in to, że konfiguracja bazy będzie przy pierwszym uruchomieniu programu, gdzie oczywiście użytkownik wprowadza np. dane firmy, ustawienia początkowe aplikacji, po uzupełnieniu danych, stworzona zostanie struktura bazy na podanym serwerze oraz wprowadzone dane początkowe, że tak powiem do odpowiednich tabel. I teraz może dla niektórych wydać się głupie pytanie... W Entity Framework przy sposobie CodeFirst, baza jest tworzona na etapie kompilacji, czy uruchomienia programu?

W razie pytań odpowiem, ewentualnie rozwinę jakąś cześć, nie chciałem za bardzo się rozpisywać...
Pozdrawiam.

0

Po co ci dwie bazy danych ? Wystarczy w zupełności jedna z, której będą korzystać aplikacje w WPF i ASP.NET. Właśnie chodzi o to w bazie danych by był do niej dostęp z różnych urządzeń: desktop, serwisy internetowe, aplikacje mobilne. Idiotyzmem jest robić dwie osobne bazy danych, i je następnie scalać. Generalnie możesz rożnie do tego podejść w sprawie jak napisać obsługę tych baz danych. I tutaj raczej zależy do tego co chcesz robić z danymi jak je przechowywać, prezentować. Generalnie jak po stronie ASP napiszesz API to możesz o te api oprzeć aplikację napisaną w WPF a przy okazji pisanie aplikacji mobilnej pod to API powinno pójść też o wiele łatwiej bo wówczas uzyskujesz z poziomu serwera dostęp do baz danych.

Co do ORM ciężko mi się wypowiedzieć bo nie korzystałem wcześniej. Generalnie sporo wielkich projektów nie używa ORM bo czasem są mało wydajne więc nawet korzystając z nich, w niektórych miejscach pisze się samemu zapytania by je przyspieszyć. Na pewno jest to ciekawe doświadczenie tym bardziej, że ORM bardzo często przewija się przez oferty pracy :). Powodzenia w pisaniu inżynierki :D

0

Niepotrzebna ta ironia na końcu, mam jeszcze rok, pytania może naiwne i głupie, chcę się po prostu zorientować wcześniej, jak stwierdzę, że nie dam rady, to zrobię to w Javie i całość zrobię w Springu. Póki co jestem mocno "nakręcony" na .NET.

Co do tematu dwóch baz. Owszem nie ma problemu w zrobieniu połączenia do jednej bazy. Ale chciałbym zrobić, że tak powiem rozdzielenie pomiędzy serwerem www dostępnym dla "świata", a serwerem bazy danych dla bazy firmowej, który stoi lokalnie w organizacji bez dostępu z zewnątrz. Może głupie rozwiązanie, na razie jestem na etapie planowania.

Co do ORMa. Robiłem aplikacje bez ORM, jak również z Hibernate. W sumie moje wątpliwości nie opierają się problemach wydajnościowych, gdyż mój projekt nie będzie należał do tych wielkich. Bardziej chodzi mi o te rzeczy, które ORM narzuca.

1

Pomysł z uzyciem dwóch baz danych wcale nie jest taki głupi, jedna lokalnie w razie braku dostepu do internetu, a druga globalnie gdzieś tam w internecie. Głupotą jest natomiast pomysł synchronizowania ich za pomocą trigerów. Ogólnie sam ten problem synchronizacji i działania aplikacji na dwóch bazach, jest sam w sobie ciekawym i wcale nie łatwym tematem na pracę dyplomową.

2
lukaszek016 napisał(a):

Niepotrzebna ta ironia na końcu, mam jeszcze rok, pytania może naiwne i głupie, chcę się po prostu zorientować wcześniej, jak stwierdzę, że nie dam rady, to zrobię to w Javie i całość zrobię w Springu. Póki co jestem mocno "nakręcony" na .NET.

No i tego się trzymaj, zawsze warto spróbować czegoś nowego. Poza tym .Net jest świetny do takich zadań (nie twierdzę że Java ze Springiem nie jest).

Co do tematu dwóch baz. Owszem nie ma problemu w zrobieniu połączenia do jednej bazy. Ale chciałbym zrobić, że tak powiem rozdzielenie pomiędzy serwerem www dostępnym dla "świata", a serwerem bazy danych dla bazy firmowej, który stoi lokalnie w organizacji bez dostępu z zewnątrz. Może głupie rozwiązanie, na razie jestem na etapie planowania.

Ale koniec końców i tak będziesz musiał to jakoś zintegrować więc tylko niepotrzebnie dołożysz sobie utrudnień. Mając osobną bazę danych dla każdego systemu cofasz się tak naprawdę do starego modelu przechowywania danych- no chyba że zaimplementujesz mikroserwisy i architekturę CQRS ale to już całkowicie inna bajka.

Co do ORM to nie wiem skąd wątpliwości- jak najbardziej warto je używać. Nie wiem skąd w dzisiejszych czasach zła opinia o szybkości ich działania- chyba niektórzy mentalnie utknęli w poprzedniej dekadzie. Pracowałem przy systemach finansowych które za krytyczny wymóg miały szybkość przetwarzania danych i nadal korzystały z ORM- tak, również Entity Framework (zaraz ktoś tutaj przyjdzie i będzie wylewał pomyje twierdząc że to zUo). Oczywiście znajdą się przypadki w których ORM faktycznie będzie za wolny i trzeba się posiłkować czystym ADO albo ewentualnie Dapper'em ale są to wyjątki których jest ułamek.

W Entity Framework przy sposobie CodeFirst, baza jest tworzona na etapie kompilacji, czy uruchomienia programu?

W trakcie uruchomienia programu. Ale ogólnie to na bazie produkcyjnej lepiej samemu ją aktualizować.

Innymi słowy postaw jedną bazę, użyj EF, NHibernate czy co tam chcesz i ciesz się życiem :)

0

Czy zamierzasz dać aplikacji ASP i aplikacji WPF bezpośredni dostęp do tej bazy ? Jeśli tak to raczej jest to błąd bo wtedy masz elementy logiki biznasowej po stronie aplikacji klienckich które takiej mieć nie powinny mieć albo wcale albo mieć tylko w stopniu wymaganym do prezentacji. Rozważ budowę WebAPI którego będziesz używał poprzez WPF i ASP.NET

0

Aventus, fakt, temat dwóch baz mocno do przemyślenia, raczej zrezygnuję z tego pomysłu.

Co do ORM. Pisząc w Springu, konfiguracja połączenia z bazą, była w pliku properties, kiedy bazy nie było to całą struktura była generowana na podstawie modelu i adnotacji.
Tutaj chcę tego uniknąć.
Miałoby to wyglądać tak, że przy pierwszym uruchomieniu użytkownik podaje dane logowania do bazy. Program sprawdza, czy baza jest na podanym serwerze, jeśli nie to po podaniu w kolejnym oknie wymaganych danych, np. dane firmy, format wydruku raportów, format wydruku etykiet, wybór domyślnych drukarek program utworzy bazę danych z odpowiednio uzupełnioną tabelą z ustawieniami.
Oczywiście przy podłączaniu do istniejącej bazy, chciałbym, aby program wykonał testy integralności odpalając zdefiniowane funkcje na serwerze.

Czy da się to zrobić w EF? Nie oczekuję odpowiedzi jak, tylko czy.

Jedyne czego oczekuję od ORMa to mapowanie, cała konfiguracja bazy i zarządzanie strukturą należy do mnie.

W2F, rozważę, ale co masz na myśli pisząc, że logikę mam w aplikacji? Jakbym używał tylko aplikacji WPF to co by to zmieniło?

2

W EF możesz wybrać podejście Database First, gdzie klasy i ich zależności są generowane na podstawie istniejącej już bazy danych. Natomiast jeśli chcesz mieć pełną kontrolę nad konfiguracją bez żadnych ograniczeń narzuconych przez ORM (jakikolwiek) i zależy Ci tylko na zautomatyzowaniu mapowania to rozważ skorzystanie z Dapper .

Co do konfiguracji to pamiętaj że EF (podejrzewam że NHibernate również) jest bardzo elastyczne.

0

No właśnie, bazę chcę zrobić samodzielnie, również klasy chcę napisać samodzielnie.

Przejrzę dokumentację tego Dappera, dzięki za pomoc!

1

Chodzi o to że podobne zadania edycji/dodawania masz zarówno po stronie aplikacji ASP.NET jak i aplikacji WPF. Pisząc hipotetycznie - jeśli obaj łaczą się bezpośrednio do bazy to jak zagwarantować że logika dodawania nowych elementów do bazy jest spójna po strinie ASP.NET i WPF. A co jeśli w jednej np w aplikacji zmieni się sposób dodawania(nowe nie-nullowalne pola w bazie) elementu, a użytkownik będzie miał starą wersję klienta ?

Rzezywiście w tej sytuacji robienie osbnego api może byc przerostem formy. Natomiast aplikacja WPF pod żadnym pozorem nie powinna miec bezpośrednio dostępu do bazy. Wtedy aplikacja ASP.NET powinna wystawiać API do którego może łączyć sie aplikacja WPF.

0

Ok rozumiem. Tzn nie do końca :) Dlaczego to WPF ma nie mieć dostępu bezpośredniego, a nie ASP? Chodzi Ci o to, że w ASP da się wystawić api? Tzn. w WPF też się da, ale api działa dopóki ktoś nie zamknie aplikacji.
Dobra, ok, ma być to aplikacja do zarządzania serwisem. Planowo miało być każdym, ale ograniczam się do serwisu komputerów etc, aby trochę uprościć. Aplikacja ASP ma służyć tylko po to, aby klient po wpisaniu powiedzmy nr naprawy i nr telefonu mógł sprawdzić status naprawy, dodatkowo poprzez formularz może zarejestrować nową naprawę. Koniec funkcjonalności. Przynajmniej na razie.

0

Pisząc API @W2K ma na myśli Web API, a więc serwis internetowy przyjmujący requesty HTTP (GET/POST/PUT/DELETE). Chodzi mu więc o to aby aplikacja (w tym przypadku klient WPF) wysyłała requesty do tego serwisu w celu wyciągnięcia/modyfikowania danych z bazy zamiast bezpośrednio komunikować się z bazą z poziomu aplikacji WPF.

0

WPF nie powinien mieć dostępu do bazy ponieważ nie ma sposobu na zapewnienie że zapytania SQL po jego stronie nie zepsują bazy ( na przykład z powodu nieaktualnej wersji aplikacji u końcowego użytkownika). Przy ASP.NET ten problem nie występuje, ponieważ kod odpowiedzialny za operacje na bazie stoi po strinie serwera którego wersją zarządzasz "Ty".

Tzn w twoim przypadku główna logika powinna zmajdować się po stronie ASP - serwera. Tzn wszytskjie operacje powinny być oprogramowane tylko po strinie ASP, dodatkowo ASP oprócz warstwy presentacji HTML, powinno wystawiać WebAPI umożliwiające klientowi WPF dostęp do danych i ich modyfikację.

0

Tak, rozumiem o co chodzi. No muszę również nad tym pomyśleć, chociaż przyznam, że trochę mi to burzy koncepcję, bo ta aplikacja ASP to miały być taki malutki dodatek.

1

Tak naprawdę to niewiele zmienia. Po rpostu kod który dotychczas chciałeś umieścić w aplikacji WPF umieścisz w ASP.NET i tyle. ;-)
Tak prawdę mówiąc na miejscu promotora nie zaakceptowałbym pracy wg Twojego pierwszego modelu. Takie podejście zadziała ale , nie tak się to robi.

0

Masz rację i powoli przekonujesz mnie do tego rozwiązania :)

Ale co do tego, że nieaktualność aplikacji WPF może popsuć bazę, bo ta jest w nowszej wersji niż program to teoretycznie można zabezpieczyć. Tzn. nie przed moją nieuwagą, bo przed tym to nawet aplikacji ASP nie zabezpieczę, ale przed sytuacją, kiedy to użytkownik odpali starszą wersję aplikacji. Nie mam doświadczenia w pisaniu takich aplikacji biznesowych więc możliwe, że gadam głupoty, ale chyba najprościej to przy aktualizacji programu zaimplementować również aktualizację struktury bazy danych. Można, tak jak program, bazę danych również wersjonować i wersję bazy zapisywać w jakiejś tabeli a program przy uruchamianiu sprawdza, czy wersja bazy zgadza się z wersją programu. Cholera, chyba za dużo pracowałem na Comarchu... :)

Promotor by zaakceptował, za to recenzent pewnie by mnie zrównał z ziemią.

1

@W2K:

WPF nie powinien mieć dostępu do bazy ponieważ nie ma sposobu na zapewnienie że zapytania SQL po jego stronie nie zepsują bazy ( na przykład z powodu nieaktualnej wersji aplikacji u końcowego użytkownika).

Można temu zapobiec przechowując w bazie danych informacje o wersji aplikacji. Jeżeli "numerek" w bazie nie zgadza się z "numerkiem" w oprogramowaniu klienckim to zwyczajnie zamykamy klienta i uruchamiamy automatyczną aktualizację do odpowiedniej wersji. Widziałem bardzo dobrze działające mechanizmy tego typu.

Prawdziwym problemem natomiast jest zapewnienie bezpieczeństwa klientom WPF czyli np. zabezpieczenie przed podsłuchaniem zapytań przez powiedzmy atak Man in the middle vide zaszyfrowanie połączenia pomiędzy klientem WPF, a bazą danych czy nawet pomiędzy klientem WPF, a proxy, który zbiera requesty.

0

Jeśli to klient będzie komunikował się z bazą to powinieneś martwić się tylko o to aby kod był zgodny z aktualną wersją bazy danych.
Co do "zepsucia" bazy to sam tego nie rozumiem- możesz rozwinąć @W2K? Jeśli kod klienta nie będzie aktualny z bazą to przy zapytaniach czy insertach kod się po prostu wysypie- nie ma tu jak psuć samej struktury bazy danych?

0

grzesiek51114, w zamierzeniu komunikacja SQL <-> WPF to połączenie wewnątrz sieci firmowej. Poza tym w connection stringu "Encrypt=True;" może by rozwiązało.

1

w zamierzeniu komunikacja SQL <-> WPF to połączenie wewnątrz sieci firmowej

Nieważne, ponieważ chęć zalogowania się jako kto inny i narobienia mu brudu zawsze w ludziach pączkuje. Osobiście zetknąłem się z paroma przypadkami podsłuchiwania ruchu przez osoby, po których nawet byś się tego nie spodziewał.

0

No tak, rozumiem. Ale przecież można nawiązywać połączenie szyfrowane z bazą.

2

@Aventus: Niekoniecznie psuć strukturę. Ale już na przykład aktualizacja znaczenia enumów(teoretycznie nie powinno się zmianiac istniejących ale róznie z tym bywa), albo zmiana polegająca na tym że dodanie zamówienia polega na dodaniu nie do 1 tabeli a do kilku, podczas gdy stary klient robi to na 1 tabli. To nie spowoduje z automatu błędów w insertach ale będzie psuć dane.

@grzesiek51114: Można poszyfrować, można powersjonowac bazę itd, tylko po co skoro można to zrobić w sposób bezpieczny nie uciekając się do rozwiąza tego typu. W sktórcie: Nie widze sytyacji w której byłoby uzasadnione utrzymywanie logiki biznesowej po stronie klienta jeśli mówimy o rozwiązaniu które jest always on-line.

1

zmiany polegająca na tym że dodanie zamówienia polega na dodaniu nie do 1 tabeli a do kilku z reguły wynikają z jakichś zmian w samym zamówieniu, np. dodania nowych pól, Wtedy bez uaktualnienia klienta i tak się nie obejdzie.

Inserty/updaty można robić za pośrednictwem stored procedures, co w dużym stopniu zabezpieczy nas przed zapisem błędnych danych,
Tyle, że EF jest mniej zorientowane na SP niż stare ADO.

0

Nikt nie mówi że klienta nie trzeba zaktualizować. Bardziej chodzi o to jak naprawdę zapewnić że będzie zaktualizowany w chwili wykonywania operacji. A procedury ? Ile nowoczesnych systemów opiera się obecnie na procedurach ? Jest to napeno jakaś metoda rozwiązania problemu, tylko po co utrudniać sobie życie l ? Debugowanie SQLa to sama przyjemność.

2
niemand napisał(a):

Inserty/updaty można robić za pośrednictwem stored procedures, co w dużym stopniu zabezpieczy nas przed zapisem błędnych danych,

Niby w jaki sposób? Błędne dane można wstawić i procedurą, i ORMem, i wykonując SQL bezpośrednio na bazie.

1

Inserty/updaty można robić za pośrednictwem stored procedures, co w dużym stopniu zabezpieczy nas przed zapisem błędnych danych,

Przecież jeżeli wymaga się od danej operacji atomowości to zawsze można zapiąć ją w transakcję. Takie rzeczy standardowo robią również ORM'y i to nic nadzwyczajnego.

0

Inserty/updaty można robić za pośrednictwem stored procedures, co w dużym stopniu zabezpieczy nas przed zapisem błędnych danych,

Przecież jeżeli wymaga się od danej operacji atomowości to zawsze można zapiąć ją w transakcję. Takie rzeczy standardowo robią również ORM'y i to nic nadzwyczajnego.

Proponując procedurę miałem na myśli to, że można w niej sprawdzić/zadbać o poprawność danych przed zapisem do bazy.
Ktoś wcześniej pisał, że np. dodamy do tabeli kolumnę not null, aplikacja o tym nie wie i wyjdzie błąd.
W procedurze możemy takie sytuacje obsłużyć. Czasami niektóre zmiany w logice wystarczy zrobić w SP, nie jest wymagany upgrade aplikacji.
Autor wątku pisał o SQL Server, obok T-SQL mamy jeszcze CLR i SP w C#.
Tyle, że SP to naturalna rzecz w ADO/Datasetach, w EF to taki kwiatek do kożucha.
Wynajdywanie błędów w kodzie SP też jest upierdliwe.

1

Jasne, że zastosowanie procedur składowanych i umieszczenie tam logiki daje pewną niezależność, ponieważ to wszystko leży warstwę niżej w stosunku do całej aplikacji. Tylko, że, jak wspomniałeś, debugowanie takiego kodu to droga przez mękę i pół biedy jeżeli są tam w miarę proste SQL'e. Prawdziwy horror zaczyna się kiedy masz przed oczami zagnieżdżone kursory [i jeszcze debugowanie tego jakie dane tam siedzą vs. wpięcie się trapem do foreacha C#] albo sytuację kiedy ktoś kiedyś wpadł na pomysł ulepszenia jakiegoś mechanizmu triggerami. Niby wszystko działa, a jednak czyta się to i debuguje koszmarnie i w dodatku zabija wydajność.

Już mówiąc szczerze wolę poświęcić jeden dzień debugując przez ORM'a i wymuszając aktualizację automatyczną apki klienckiej niż siedzieć trzy dni, zastanawiając się nad magią procedur składowanych gdzie klient wciąż nie ma działającego poprawnie mechanizmu. No, a jak wiadomo "czas to piniundz".

Oczywiście nie wszystko ogarnie się przez ORM ale nie należy przesadzać w drugą stronę.

1
niemand napisał(a):

W procedurze możemy takie sytuacje obsłużyć.

No, ale jak? Jeśli dane są wymagane, to trzeba je do tabeli przekazać. Tak czy siak będziemy musieli zaktualizować aplikację, więc jaki zysk z wprowadzania dodatkowej warstwy procedur?
No chyba, że chcemy w nich połykać błędy i udawać, że wszystko jest ok. ;)

Czasami niektóre zmiany w logice wystarczy zrobić w SP, nie jest wymagany upgrade aplikacji.

I najlepiej je wtedy puścić bokiem na produkcję bez informowania nikogo o tym ani wrzucania skryptów upgradujących do repozytorium. To ulubiony sposób działania tzw. programistów baz danych. Potem idzie normalny deployment bazy, aplikacja przestaje działać i nikt nie wie dlaczego.

Tyle, że SP to naturalna rzecz w ADO/Datasetach, w EF to taki kwiatek do kożucha.

SP to jest bardzo naturalna rzecz, ale tylko tam, gdzie faktycznie są potrzebne i w czymś pomagają. Np. rozwiązują problem wydajnościowy poprzez realizowanie operacji wsadowych albo ciężkich kalkulacji, którym taki biedaORM jak EF nie jest w stanie podołać.

0

W procedurze możemy takie sytuacje obsłużyć.
No, ale jak?
Dyskusja zaczęła się od tego, żeby student nie umieszczał logiki w aplikacji desktopowej, bo gdy zmienią się reguły a aplikacja nie zostanie zaktualizowana to do bazy trafią śmieci.
Aktualizując bazę przez SP możemy np. rzucić wyjątkiem przy błędnych danych.

kursory zagnieżdżone
W praktyce, ale to bardziej przy odczycie danych i agregacji/filtrowaniu wg skomplikowanych reguł, często można ich uniknąć posługując się CLR-em/C#.
Zapisuje dane to #tmp1, odczytuję w CLR-1, przetworzony/zagregowany wynik do #tmp2., potem jakiś update/join, CLR-2... :)
Stosuję to w aplikacjach na zamówienie, jak by wyglądał deployment/aktualizacje dla setek instalacji - nie wiem.

0 użytkowników online, w tym zalogowanych: 0, gości: 0