22

I was recently asked to assist another team in building an ASP .NET website. They already have a significant amount of code written -- I was specifically asked build a few individual pages for the site.

While exploring the code for the rest of the site, the amount of DataTables being constructed jumped out at me. Being a relatively new in the field, I've never worked on an application that utilizes a database as much as this site does, so I'm not sure how common this is. It seems that whenever data is queried from our database, the results are stored in a DataTable. This DataTable is then usually passed around by itself, or it's passed to a constructor. Classes that are initialized with a DataTable always assign the DataTable to a private/protected field, however only a few of these classes implement IDisposable. In fact, in the thousands of lines of code that I've browsed so far, I have yet to see the Dispose method called on a DataTable.

If anything, this doesn't seem to be good OOP. Is this something that I should worry about? Or am I just paying more attention to detail than I should? Assuming you're most experienced developers than I am, how would you feel or react if someone who was just assigned to help you with your site approached you about this "problem"?

Justin Rusbatch
  • 3,992
  • 2
  • 25
  • 43
  • I's not OOP. Some OOP techniques can still be used, but lots of restrictions that define OOP or even typed variables are easily circumvented. If you used to work in clean OOP environment, you'll feel rather... uncomfortable. – DK. Oct 23 '09 at 14:37

5 Answers5

26

Datatables can be used for good and evil.

Acceptable Use

I would find the following to be an acceptable use of a datatable or a 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"]; } }
    // ...
}

The class above is ok because it maps a DataRow to a typesafe class. Instead of working with strings and untyped datarows, now you have real datatypes and intellisense to assist you. Additionally, if your database schema changes, you can modify a column name in your object, instead of modifying the column name everywhere its used. Finally, you can map ugly column names like "dtaccount_created" to a property named "AccountCreated".

Of course, there's really no good reason to write this wrapper class, since Visual Studio will automatically generate typed datasets for you. Or, as an alternative, a good ORM like NHibernate allows you to define classes similar to the one above.

Whether you you should use plain old ADO.NET, typed datasets, or a full fledged ORM depends on the requirements and complexity of your application. Its hard to say whether your team is doing the right thing withotu actually seeing some sample code.

Additionally, I occasionally find it useful to databind lists and grids with a datatable, because changes to the underlying datarow will automatically cause the GUI to refresh. If you create your own type-safe wrapper, then you need to implement the IPropertyChanging and IPropertyChanged interfaces manually.

Unacceptable Use

Unfortunately, I've seen programmers use datatables for ad hoc containers, alternatives to classes, etc. If you see your team doing this, throw rocks at them. That style of programming just doesn't work in a statically typed language, and its going to make development a nightmare.

Main problem with datatables: they aren't typed, so you can't do anything useful with them without giving them a string and casting whatever mystery object they contain into the right type. Additionally, refactoring a column name is nearly impossible to automate since they are based on strings, so you can't rely on intellisense to help you write correct code, and you can't catch errors at compile time.

I say trust your instinct: if you think design is flakey, it probably is.

Juliet
  • 80,494
  • 45
  • 196
  • 228
  • 6
    **Unacceptable Use** I have exact the same problem in my company in every projects that other programmer developed, and this is really a nightmare. After using ORM, design patterns, MVC, lambda expressions etc. it is looks like a horror. Avoid this as much as you can. – Alexanderius Apr 30 '13 at 09:57
  • 1
    as an addition here you should use .Field and .SetField extensions to DataRow to retrieve and set DataRow data. – InContext Dec 03 '14 at 09:55
8

This is definitely something you should worry about - see a related post on the importance of Disposing DataTables.

DataTables are finalizable: if you're not actively disposing them, they're hanging around much longer than Gen0 collections and killing memory.

To measure the extent of damage in your application, you can take a memory dump using WinDbg and look at the sheer number of DataTable instances (!dumpheap -stat -type System.Data.DataTable) then look at the largest data tables in memory.

This is a common pitfall in ASP.NET applications, and one that can land you in serious trouble. If you're using shared (cached) instances of DataTables, take care to note that view filters change the original instance, they don't generate a new copy.

Also make sure that queries populating the DataTables have some reasonable limit on the number of rows returned, otherwise changes to your data can suddenly baloon memory and destabilize your application pool.

Community
  • 1
  • 1
Nariman
  • 6,368
  • 1
  • 35
  • 50
  • DataTable don't need to be disposed, they are managed objects. This answer is comparing apples and oranges. Whatever you put in an ASP.NET cache can live there until the app-pool is recycled, that's not DataTable specific. – Tim Schmelter Oct 13 '17 at 14:19
  • ...and `Cases` are not finalizable? (all classes are) i believe this whole answer is flawed, please double check what you are saying. All of what you have said could be applied to generics, if that's what you intend to use as an alternative, if not then please explain. – Seabizkit Dec 11 '19 at 18:08
7

At a very high level, Software system architecture can be characterized as using one of several "Enterprise Level Patterns", Transaction script, Table Model, Domain Model, or Service Layer. If the system you are reviewing is using the Table Model pattern, then you would expect to see more use of DataTables and DataSets than in, say, a system that was designed using Domain Model or one of the other patterns.

However, as software system design methodologies have evolved over the past few years, it has generally been understood that complex systems do not fare well using Transaction script or Table Model architectures. This is generally because in systems designed using these patterns, functionality is generally much more intertwined, and interrelated, and as complexity grows, the amount of functional, or module interdependence grows exponentially, and becomes too hard to manage very quickly. So, depending on how complex your particular system is, yes, you should be suspicious if DataSets and/or DataTables are used throughout multiple layers of the system. This may be a sign that the system designer was/is using Table Model (consciously or unconsciously) where he/she should be using Domain Model or Service Layer architecture.

Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
  • 2
    Yeah I think you could easily replace "Table Model" with "Design Fail" – Chris Marisic Oct 23 '09 at 14:51
  • @Chris, you put useless comments in here. If you do, then please add a few lines explaining WHY DataTables are a bad practice. – Janis Veinbergs Oct 23 '09 at 15:03
  • 1
    @Javis, are you really making an argument that DataTables have any use of existence since generics were released in .NET 2.0? – Chris Marisic Oct 23 '09 at 15:28
  • 12
    @Chris, no he is simply suggesting that when you make a negative comment, add some facts to help the reader understand the point you're making. This forum is to help people, not to show off how smart you are. – Charles Bretana Oct 23 '09 at 15:45
  • Could you please have a look on this question, it is related? http://stackoverflow.com/questions/18562928/why-using-datatable-in-ui-is-wrong – Nancy Sep 01 '13 at 21:22
3

yes I would be careful here...

I had to look after a vb.net web app for about 2 months before I could re-write it all in C# .... I love C#, VB makes me want to hurl...

Anyway, in the old app the previous developer had loaded data from the database into a datatable and then passed the datatable around a few methods which did absolutely nothing to the datatable, only for it to be assigned to a gridview. I was in utter disbelief.

To make matters worse, there were times where he would actually dump the DataTable into a session... for no reason at all.

DataTables etc are great, but only use them if you 'really' need to use them. The developer was soo bad that on search page he actually dumped all 5000 products from the database into a datatable and then performed a search on the datatable instead of performing the search in a stored procedure (ie. on SQL SERVER)

Dalbir Singh
  • 2,629
  • 3
  • 26
  • 29
  • 2
    That last paragraph for a database of only 5000 products (depending complexity of what is a product) just caching the entire table in memory would probably be the best solution and handle searches in C# directly. Of course I doubt he actually cached the table after getting the 5000 rows... – Chris Marisic Oct 23 '09 at 14:49
  • @Dal: For what its worth, a few unnecessary parameters and unnecessary objects in the session is forgivable; and storing keeping a datatable of 5000 objects around for local querying can sometimes outperform a database in terms of memory and speed. No, TRWTF is a total re-write of a working app from VB.NET to C# because its not your favorite pet language. Get over yourself. – Juliet Oct 23 '09 at 15:40
  • @Chris... the search was for a product page on a public facing web site, you simply enter a few keywords and it will search field such as 'Colour, Detail, ShortDetail, Size' etc ... I don't know but performing this logic inside a asp.net page (business layer) just doesn't seem like the best approach with that many records to me... since it has been rewritten to perform the search logic within the SP it has been a hell of a lot faster anyway. – Dalbir Singh Oct 23 '09 at 16:20
  • @Juliet The vb.net app was riddled with bugs and needed to be rewritten anyway - I took over once the old developer left... I was hired as a C# dev and it was agreed by management before-hand that all apps need to be in C#. Having to use VB.NET is probably the most painful thing 'SOME' devs like me can do when you've worked with Java,C#,PHP.......................and then VB.NET waaaaaay over there in mystery 'DIM' land – Dalbir Singh Oct 23 '09 at 16:23
  • this answer has to do with how it was used, not as a whole. if you write bad code then its bad code. trying to use as a cache... which wasn't implemented properly doesn't make datatable bad, makes just for incomplete code. aka if he used as a cache which was smart enough to know when to load from db and wen not too, then it would of work great... like i said nothing to do with datatable itself. – Seabizkit Dec 11 '19 at 18:14
1

Using a DataTable can be a lazy/inefficient way of storing data. There is significant overhead in doing so. You are right to be concerned, although the developer(s) may have a real issue hearing how poorly they have designed this app. Will management be behind you, in your goal of creating a better quality product? Will the associated delay in development be something they can accept?

stoogots2
  • 11
  • 1
  • 1
    How is lazy is inefficient? If at all I would assume it's the opposite? – nawfal Apr 29 '17 at 01:21
  • yes please explain, i tired of reading incorrect statements with little or no understanding, of the under lying mechanics. – Seabizkit Dec 11 '19 at 18:05