LINQ query on a DataTable
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
DataTable is an older but still common .NET container for in-memory tabular data. LINQ makes it much easier to filter, sort, and project rows than manual loops do, but the key detail is that a DataTable must first be exposed as an enumerable sequence of DataRow values.
Why AsEnumerable Matters
DataTable.Rows is not directly a generic IEnumerable<DataRow>, so standard LINQ operators do not light up until you call AsEnumerable(). That extension method is defined in System.Data.DataSetExtensions.
Using Field<T> is better than indexing with row["Age"] followed by a cast. It is clearer, strongly typed, and handles DBNull more predictably when used with nullable types such as int?.
Filtering and Sorting Rows
Once the table is enumerable, you can compose ordinary LINQ queries. Filtering and sorting are the most common tasks:
This pattern is much more maintainable than nested for loops with repeated casting. It also makes the intent of the code obvious to the next developer.
Projecting into Stronger Shapes
You are not limited to returning DataRow values. A common improvement is to project rows into anonymous objects or domain types:
Projection is useful when you want type-safe downstream code and do not want other methods reaching back into the raw DataRow.
Aggregation and Grouping
LINQ is also a clean way to summarize table data. Grouping by one column and computing counts or totals is concise:
That pattern replaces a fair amount of manual dictionary bookkeeping. It is especially useful in reporting code and legacy migration work where DataTable is still the integration boundary.
Creating a Filtered DataTable Again
Sometimes the result must remain a DataTable because another API expects one. In that case, use CopyToDataTable() after filtering:
The Any() check matters. CopyToDataTable() throws if the sequence is empty, so table.Clone() is a safe way to preserve the schema without rows.
Dealing with Nulls and DBNull
Real DataTable values often contain database nulls. If you treat them as non-nullable types, you can trigger runtime exceptions. Use nullable fields when the column may be empty:
That keeps null-handling logic explicit instead of scattering DBNull.Value checks throughout your query code.
Common Pitfalls
- Forgetting
AsEnumerable(), which makes theDataTablelook like it does not support LINQ. - Using
row["Column"]with direct casts instead ofField<T>, which is harder to read and easier to break with nulls. - Calling
CopyToDataTable()on an empty sequence and getting an exception. - Assuming database nulls behave like C#
nullwithout using nullable generic types. - Running the same deferred query many times instead of materializing it with
ToList()when repeated enumeration is intended.
Summary
- Start LINQ queries on
DataTablewithAsEnumerable(). - Prefer
Field<T>for typed column access and better null handling. - Use
Where,OrderBy,Select, andGroupByto replace manual row loops. - Convert back to
DataTablewithCopyToDataTable()only after checking for empty results. - Project into stronger shapes when later code should not depend on raw
DataRowaccess.

