DataTable vs. BindingList<T>

We were having a discusion today about the merits of using DataTables vs. BindingList<T> (a generic in .NET 2.0) for loading up domain objects into the UI layer (say to display on a grid). My gut feel is telling me DataTables are evil and wrong, but I don't have a lot of hard evidence to choose one over the other. We brainstormed some pros and cons for each and they're listed below.

DataTable

Pros

Simple to implement, not much code needed

Can use select statements to retrieve values

Change events are managed within the object automagically

Display handling for errors built-in (when binding to grids)

Cons

Human errors (typos on column names for example) can be exposed at runtime and can't be easily tested

Must implement some mechanism (like a decorator pattern) to respond to change events

More short term investment to learn and implement

Are we wrong with our list or is there something that you've come across with your dealings with the two approaches?

13 Comments

I'd go for bindinglist. The thing is that with a datatable, the dataview which is bound to the control also has to do the same things as bindinglist has to do: both implement ITypedlist and provide property info for the objects in the list/dataview (done once).

A dataview also iterates through items to find rows, though it could create indexes, however I don't think that will matter that much.

About bloatware: code of a class is shared among all instances of the class. This means that if you instantiate a lot of objects of the same class, you won't lose extra memory if the class is big: all objects share the same code / IL in memory

Go with BindingList. Its pros outweight the DataTable pros. The other concern with DataTables is the possiblity of Microsoft implementing another data access framework (DAO,RDS,ADO,ADO.NET, etc.). You can't go wrong with using business objects. It is more work but you will have a better solution in the long run.

Also, Brian Noyes has a great book on .Net 2.0 Databinding. It has examples on how to wire your business objects up to easily maintain their data changes.

I'm a fan of BindingList as well. The one thing you lose with BindingList though is the sorting and filtering that are available over DataTables through the DataView. You can filter and sort the DataView without affecting the underlying table. Very nice.

Unfortunately, there is no such "out of the box" view for arbitrary domain objects in a BindingList. To solve this, I wrote ObjectListView, which provides a sorted, filtered view over any List (all without altering the underlying list). Check it out at my blog: www.teamjohnston.net/cs/blogs/jesse.

There is nothing inherently wrong with DataTables. Just use them when the pros outweigh the cons. Not every application is going to get Amazon's traffic. If I'm writing a one-off utility for my own personal use to read in an Excel spreadsheet, for example, I'll read it directly into a DataSet with an OleDbAdapter and bind to the table without bothering to convert to objects.

In short, I use DataTables for quick and dirty but I don't get attached to them. They're the first thing in the list of refactorings if the app starts growing even a little.

Using a strongly typed DataTable would negate the con regarding human errors. However its inabillity to map DBNull to Nullable is a strike out for me.

I recently looked at the innards of the Select mechanism and concluded that performance-wise & maintainabillity you're much better off using either Linq (the compile time checking) or just rolling your own index / iterator...

The biggest annoyance with BindingList is that it doesn't natively support sorting. I can't believe MS left that out. It's not too horribly difficult to subclass and add, but it's annoying that we have to.

(a) I started building a mission critical application by building custom entity classes based on a common base class for business rules and state tracking. Sooner I found that BindingList does not have filter support.

(b) Then I started building the project with typed dataset approach. It was found that you can't set numeric keys (foreign keys) to DBNull. Another issue is that Typed Datatable generated 10000 lines of code just for 2-3 tables. That is not acceptable.

(c) Untyped datatable: you can't cancel the columnchanging operation from the columnchanging event. If enduser enters a wrong value, you can't simply reject it in the column changing event. The result is that the status of the row is set to 'modified'.

The end result is that you end up messing code. Writing workarounds and validation logic on the frontend. And your code starts growing and growing.