DataTable
List conversion
C# programming
data manipulation
.NET

How to convert a column of DataTable to a List

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Converting one DataTable column into a List is a common cleanup step when older ADO.NET code needs to feed newer application logic or APIs that expect generic collections. The most reliable approach is to project rows with LINQ, use the correct typed accessor, and decide up front how null values and conversion failures should be handled.

Build the DataTable

A DataTable stores values as object, so your first task is deciding what type the list should hold. If the column is conceptually strings, project strings. If it is integers, read integers directly instead of converting everything through text.

csharp
1using System;
2using System.Collections.Generic;
3using System.Data;
4using System.Linq;
5
6var table = new DataTable();
7table.Columns.Add("Id", typeof(int));
8table.Columns.Add("Name", typeof(string));
9
10table.Rows.Add(1, "Ada");
11table.Rows.Add(2, "Grace");
12table.Rows.Add(3, "Linus");

Use LINQ with AsEnumerable

The standard pattern is AsEnumerable, followed by Select, followed by ToList. This is concise and easy to read.

csharp
1List<string> names = table
2    .AsEnumerable()
3    .Select(row => row.Field<string>("Name"))
4    .ToList();
5
6Console.WriteLine(string.Join(", ", names));

Field<T> is preferable to direct index access because it gives you typed results and integrates cleanly with DBNull handling.

Convert Numeric Columns to Typed Lists

If the source column already has a numeric type, read it as that type.

csharp
1List<int> ids = table
2    .AsEnumerable()
3    .Select(row => row.Field<int>("Id"))
4    .ToList();
5
6Console.WriteLine(string.Join(", ", ids));

This avoids unnecessary boxing and parsing. It also makes errors more obvious if the data does not match the schema you think you have.

Handle Nulls Deliberately

Database data often contains nulls. For nullable columns, project to nullable types or substitute a default value.

csharp
1table.Rows.Add(4, DBNull.Value);
2
3List<string> safeNames = table
4    .AsEnumerable()
5    .Select(row => row.Field<string>("Name") ?? "Unknown")
6    .ToList();
7
8Console.WriteLine(string.Join(", ", safeNames));

If you need to preserve the distinction between missing and present values, use List<string?> or List<int?> where appropriate.

Filter While Converting

Often the list should contain only a subset of the rows. Add filtering before ToList.

csharp
1List<string> selectedNames = table
2    .AsEnumerable()
3    .Where(row => row.Field<int>("Id") >= 2)
4    .Select(row => row.Field<string>("Name"))
5    .Where(name => !string.IsNullOrWhiteSpace(name))
6    .ToList();
7
8Console.WriteLine(string.Join(", ", selectedNames));

This keeps the transformation in one readable pipeline instead of splitting it across several loops.

A Loop-Based Option

LINQ is usually the clearest solution, but an explicit loop is fine if you need custom branching or more detailed error handling.

csharp
1var result = new List<string>();
2
3foreach (DataRow row in table.Rows)
4{
5    var name = row.Field<string>("Name");
6    if (!string.IsNullOrWhiteSpace(name))
7    {
8        result.Add(name);
9    }
10}
11
12Console.WriteLine(string.Join(", ", result));

Use this style when the projection is more complex than a simple column read.

Common Pitfalls

A common mistake is using row["Name"].ToString() for everything. That hides null handling, can turn DBNull into an empty-looking string, and makes typed failures harder to detect. Another problem is forgetting to reference System.Data.DataSetExtensions, which provides AsEnumerable in older project setups.

Be careful when the column type in the DataTable does not match the type you request in Field<T>. If the table stores strings and you ask for int, you will get runtime errors. In that case either fix the schema or project with parsing logic instead of assuming a typed column exists.

Summary

  • use AsEnumerable, Select, and ToList for the standard conversion pattern
  • prefer Field<T> over raw index access for typed reads
  • project numeric columns to numeric lists instead of converting through strings
  • decide explicitly how nulls should be handled
  • switch to an explicit loop when conversion rules become more complex than a simple projection

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.