Datasets are not for everything (and neither XML)

First of all, let me tell you that datasets are wonderful, especially if you have to do CRUD operations on relational records. But that doesn't mean they are always the best choice. Ditto for XML. With the obvious statement out of the way, let me tell you this little tale:

My pal Sandra needed to execute a process except for a group of operations, moreover, this group of "forbidden" operations could be changed at runtime. So, to begin with, Sandra defined an XML file with the forbidden operations:

<ForbiddenOperations>

  <Operation>Destroy</Operation>

  <Operation>Kill</Operation>

  <Operation>Maime</Operation>

</ForbiddenOperations>

Then, she populated a dataset with the contents of the XML file:

DataSet dataSet = new DataSet();

dataSet.ReadXml(@"..\..\ForbiddenOperations.xml");

And now, she could execute the process, except for forbidden operations, like so:

DataTable operationsTable = dataSet.Tables[0];

DataRow[] foundRows = operationsTable.Select("Operation_Text='" + operation + "'");

if (foundRows.Length == 0)

{

  // It isn't a forbidden operation, so do the process

}

It works, and it uses just a few lines of code. OTOH, it's terribly inefficient. To begin with, reading an XML file to populate a dataset demands a lot of resources and the file becomes a semaphore. Furthermore, the Select() method scans the table linearly, interpreting the expression for every row. If the table has many rows or the process is invoked many times, the response time will suffer noticeably.

Which is the alternative? First, let's put the forbidden operations in the App.config file:

<appSettings>

  <add key="forbiddenOperations" value="Destroy,Kill,Maime"></add>

</appSettings>

Then, populate a string dictionary with those operations:

string[] forbiddenOperations = ConfigurationSettings.AppSettings["forbiddenOperations"].Split(',');

StringDictionary forbiddenOperationsDictionary = new StringDictionary();

foreach (string operation in forbiddenOperations)

{

  forbiddenOperationsDictionary.Add(operation, operation);

}

And finally, you can execute the process, except for forbidden operations, like so:

if (!forbiddenOperationsDictionary.ContainsKey(operation))

{

  // It isn't a forbidden operation, so do the process

}

The first and last parts are more compact than in the first solution, even though the second part takes more lines. But the whole process is far more efficient and fast.

So, even though datasets are great, don't use them for everything, in particular don't use them as a dictionary or a cache, if you want to find objects or records by a certain key it's far better to use a dictionary. Ditto, for XML.

No Comments