2009-10-23 13 views
16

Niedawno zostałem poproszony o pomoc innemu zespołowi w budowie strony ASP .NET. Mają już znaczną ilość kodu napisanego - specjalnie poprosiłem o zbudowanie kilku pojedynczych stron dla witryny.Czy nadmierne używanie DataTable jest złe?

Podczas eksploracji kodu dla pozostałej części witryny, ilość skonstruowanych DataTables wyskoczyła na mnie. Będąc stosunkowo nowym w tej dziedzinie, nigdy nie pracowałem nad aplikacją, która korzysta z bazy danych tak bardzo, jak ta witryna, więc nie jestem pewien, jak jest to powszechne. Wydaje się, że za każdym razem, gdy dane są pobierane z naszej bazy danych, wyniki są przechowywane w DataTable. Ta DataTable jest zwykle przekazywana osobno lub przekazywana do konstruktora. Klasy zainicjowane przy użyciu DataTable zawsze przypisują DataTable do pola prywatnego/chronionego, jednak tylko kilka z tych klas implementuje IDisposable. W rzeczywistości w tysiącach linii kodu, które dotąd przeglądałem, nie widziałem jeszcze metody Dispose, która wywołałaby DataTable.

Jeśli cokolwiek, to nie wydaje się być dobrym OOP. Czy to jest coś, o co powinienem się martwić? Czy po prostu zwracam większą uwagę na szczegóły niż powinienem? Zakładając, że jesteś najbardziej doświadczonym programistą niż ja, jak byś się czuł lub zareagował, gdyby ktoś, kto został właśnie przydzielony do pomocy w twojej witrynie, skontaktował się z Tobą w sprawie tego "problemu"?

+0

Nie jestem OOP. Niektóre techniki OOP nadal mogą być używane, ale wiele ograniczeń, które definiują OOP lub nawet wpisane zmienne, można łatwo obejść. Jeśli pracowałeś w czystym środowisku OOP, poczujesz się raczej ... nieswojo. –

Odpowiedz

17

Pliki danych mogą być używane dla dobra i zła.

dopuszczalnego użytkowania

chciałbym znaleźć następujące być dopuszczalne stosowanie DataTable lub DataRow:

public class User 
{ 
    private DataRow Row { get; set; }; 
    public User(DataRow row) { this.Row = row; } 

    public string UserName { get { return (string)Row["Username"]; } } 
    public int UserID { get { return (int)Row["UserID"]; } } 
    public bool IsAdmin { get { return (bool)Row["IsAdmin"]; } } 
    // ... 
} 

powyżej Klasa jest ok ponieważ odwzorowuje DataRow Do classsafe class. Zamiast pracować z ciągami i bez typów datariów, teraz masz prawdziwe typy danych i intellisense, które ci pomogą. Ponadto, jeśli zmieni się schemat bazy danych, można zmodyfikować nazwę kolumny w obiekcie, zamiast modyfikować nazwę kolumny wszędzie tam, gdzie jest używana. Na koniec możesz odwzorować brzydkie nazwy kolumn, takie jak "dtaccount_created", do właściwości o nazwie "AccountCreated".

Oczywiście nie ma powodu, aby pisać tę klasę opakowania, ponieważ Visual Studio automatycznie wygeneruje dla ciebie typed datasets. Lub, alternatywnie, dobre ORM jak NHibernate pozwala na zdefiniowanie klas podobnych do powyższych.

Niezależnie od tego, czy powinieneś używać zwykłego starego ADO.NET, wpisane zestawy danych, czy pełnoprawny ORM zależy od wymagań i złożoności aplikacji. Trudno powiedzieć, czy Twój zespół robi to, co słuszne, bo naprawdę zobaczył jakiś przykładowy kod.

Co więcej, czasami okazuje się przydatna do databind list i siatki z datatable, ponieważ zmiany w bazowej danych automatycznie spowodują odświeżenie GUI. Jeśli utworzysz własne opakowanie bezpieczne dla typu, musisz ręcznie zaimplementować interfejsy IPropertyChanging i IPropertyChanged.

Niedopuszczalne użycie

Niestety, widziałem programiści użyć DataTables dla pojemników ad hoc alternatywy dla klas itp Jeśli widzisz swój zespół robi to, rzucać kamieniami w nich. Ten styl programowania po prostu nie działa w statycznie napisanym języku, a jego rozwój może stać się koszmarem.

Główny problem z datatables: nie są wpisane, więc nie można zrobić z nimi nic użytecznego, nie podając im napisu i nie rzucając żadnego tajemniczego obiektu w odpowiedni typ. Dodatkowo, refaktoryzacja nazwy kolumny jest prawie niemożliwa do zautomatyzowania, ponieważ są one oparte na łańcuchach, więc nie można polegać na intellisense, aby pomóc Ci napisać poprawny kod, i nie możesz złapać błędów podczas kompilacji.

Mówię zaufać twojemu instynktowi: jeśli myślisz, że projekt jest flakey, prawdopodobnie tak jest.

+4

** Niedozwolone użycie ** Mam dokładnie ten sam problem w mojej firmie w każdym projekcie, który opracował inny programista, a to jest naprawdę koszmar. Po użyciu ORM, wzorców projektowych, MVC, wyrażeń lambda itp. Wygląda to jak horror. Unikaj tego tak bardzo, jak możesz. – Alexanderius

+1

+1 za piękne wyjaśnienie @ Juliet! – Shiva

+1

jako dodatek należy użyć rozszerzeń .Field i .SetField do DataRow w celu pobrania i ustawienia danych DataRow. – InContext

3

tak byłbym ostrożny ...

musiałem szukać po vb.net aplikacji internetowej przez około 2 miesiące przed I może ponownie napisać to wszystko w C# .... Kocham C#, VB sprawia, że ​​chcę rzucić ...

Wcześniej w starej aplikacji poprzedni programista wczytał dane z bazy danych do datatable, a następnie przekazał datatable za pomocą kilku metod, które nie miały absolutnie nic wspólnego z datatable, tylko dla ma być przypisany do widoku siatki. Byłem w zupełnym niedowierzaniu.

Na domiar złego, zdarzały się sytuacje, w których faktycznie zrzuciłby DataTable do sesji ... bez żadnego powodu.

DataTables itp. Są świetne, ale używaj ich tylko wtedy, gdy "naprawdę" musisz ich użyć. Deweloper był tak zły, że na stronie wyszukiwania faktycznie rzucił wszystkie 5000 produktów z bazy danych do datatable, a następnie wykonał wyszukiwanie w datatable zamiast wykonywania wyszukiwania w procedurze przechowywanej (tj. Na SQL SERVER)

+2

Ten ostatni akapit dla bazy danych zawierającej tylko 5000 produktów (w zależności od złożoności tego, co jest produktem) po prostu buforowaniu całej tabeli w pamięci byłby prawdopodobnie najlepszym rozwiązaniem i obsługi wyszukiwania bezpośrednio w języku C#. Oczywiście wątpię, czy rzeczywiście zapisał w tabeli po zdobyciu 5000 wierszy ... –

+0

@Dal: Na ile jest to warte, kilka niepotrzebnych parametrów i niepotrzebnych obiektów w sesji jest do wybaczenia; a przechowywanie danych z 5000 obiektów wokół lokalnych zapytań może czasami przewyższać bazę danych pod względem pamięci i szybkości. Nie, TRWTF to całkowite przeprojektowanie działającej aplikacji z VB.NET na C#, ponieważ nie jest to twój ulubiony język zwierząt. Zdejmij się. – Juliet

+0

@Chris ... wyszukiwanie dotyczyło strony produktu na publicznej stronie internetowej, wystarczy wpisać kilka słów kluczowych i będzie to pole wyszukiwania, takie jak "Kolor, szczegół, krótka wiadomość, rozmiar" itp. ... Nie chcę wiem, ale wykonanie tej logiki na stronie asp.net (warstwa biznesowa) po prostu nie wydaje mi się najlepszym podejściem do tej liczby rekordów ... ponieważ zostało przepisane, aby wykonać logikę wyszukiwania w SP, było i tak piekło o wiele szybciej. – Dal

5

At bardzo wysoki poziom, Architektura systemu oprogramowania może być scharakteryzowana jako przy użyciu jednego z kilku "wzorców poziomu przedsiębiorstwa", Transaction script, Table Model, Domain Model lub Service Layer. Jeśli przeglądany system korzysta ze wzoru tabeli Tabela, należy spodziewać się większego wykorzystania DataTables i DataSet niż w, powiedzmy, systemie, który został zaprojektowany przy użyciu modelu domeny Domain Model lub jednego z innych wzorów.

Jednakże, ponieważ metodologia projektowania systemów oprogramowania ewoluowała w ciągu ostatnich kilku lat, ogólnie zrozumiałe jest, że złożone systemy nie radzą sobie dobrze z wykorzystaniem skryptu transakcji lub architektur modeli tabel. Dzieje się tak na ogół dlatego, że w systemach zaprojektowanych z wykorzystaniem tych wzorców funkcjonalność jest na ogół dużo bardziej powiązana i powiązana, a wraz ze wzrostem złożoności ilość funkcjonalnej lub modułowej współzależności rośnie wykładniczo i staje się zbyt trudna do zarządzania bardzo szybko. Tak więc, w zależności od tego, jak skomplikowany jest dany system, tak, powinieneś podejrzewać, jeśli DataSets i/lub DataTables są używane w wielu warstwach systemu. Może to być oznaką, że projektant systemu używa/stosuje model tabeli (świadomie lub nieświadomie), w którym powinien używać architektury modelu domeny lub warstwy usług.

+2

Tak, myślę, że można łatwo zastąpić "Table Model" z "Design Fail" –

+0

@Chris, umieszczasz tutaj niepotrzebne komentarze. Jeśli to zrobisz, dodaj kilka linijek wyjaśniających DLACZEGO DataTables to zła praktyka. –

+1

@Javis, czy naprawdę argumentujesz, że DataTables ma jakiekolwiek zastosowanie, ponieważ generics zostały wydane w .NET 2.0? –

6

Jest to zdecydowanie coś, o co należy się martwić - patrz odpowiedni wpis: on the importance of Disposing DataTables.

DataTables są finalizowalne: jeśli nie aktywnie je wyrzucacie, są one zawieszone o wiele dłużej niż zbiory Gen0 i zabijają pamięć.

Do pomiaru stopnia uszkodzeń w aplikacji, można zrobić zrzut pamięci przy użyciu WinDbg i spojrzeć na samą liczbę wystąpień DataTable (! Dumpheap -stat -type System.Data.DataTable), a następnie spojrzeć na largest data tables in memory.

Jest to typowa pułapka w aplikacjach ASP.NET, która może narazić Cię na poważne kłopoty. Jeśli używasz współdzielonych (buforowanych) instancji DataTables, zwróć uwagę, że filtry widoku zmieniają oryginalne wystąpienie, nie generują nowej kopii.

Upewnij się również, że zapytania wypełniające DataTables mają rozsądny limit liczby zwróconych wierszy, w przeciwnym razie zmiany danych mogą nagle doprowadzić do utraty pamięci i destabilizacji puli aplikacji.

+0

DataTable nie muszą być usuwane, są obiektami zarządzanymi. Ta odpowiedź polega na porównaniu jabłek i pomarańczy. Cokolwiek umieścisz w pamięci podręcznej ASP.NET, możesz tam mieszkać do momentu, aż pula aplikacji zostanie poddana recyklingowi, to nie jest specyficzne dla DataTable. –

1

Używanie DataTable może być leniwym/nieefektywnym sposobem przechowywania danych. W tym przypadku istnieje znaczny nadmiar. Masz rację, ale deweloperzy mogą mieć problem z usłyszeniem, jak kiepsko zaprojektowali tę aplikację. Czy zarządzanie będzie za Tobą, w twoim celu stworzenia produktu lepszej jakości? Czy powiązane opóźnienie w rozwoju będzie czymś, co może zaakceptować?

+0

W jaki sposób leniwy jest nieefektywny? Jeśli w ogóle, zakładam, że jest odwrotnie? – nawfal

Powiązane problemy