I would use a little linq magic on the datatable.
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("AccountNumber", typeof(System.Int32)));
dt.Columns.Add(new DataColumn("AccountName", typeof(System.String)));
for (int ii = 0; ii < 20; ii++)
dt.Rows.Add(new object[]{ii, "abc" + ii.ToString()});
dt.Rows[6][0] = 5;
dt.Rows[7][0] = 5;
dt.Rows[8][0] = 5;
//using grouping to isolate groups with just one item
var groupedRows = from row in dt.Select("", "AccountName ASC")
group row by row["AccountNumber"] into rowGroup
where rowGroup.Count() == 1
select rowGroup;
foreach (var group in groupedRows)
foreach(DataRow dr in group)
Console.WriteLine("Account #: {0} Account name: {1}", dr["AccountNumber"], dr["AccountName"]);
//using nested select to avoid grouping
Console.WriteLine();
Console.WriteLine("Nested select");
var z = from row in dt.Select()
where (from x in dt.Select() where (int) x["AccountNumber"] == (int) row["AccountNumber"] select x).Count() == 1
orderby row["AccountName"]
select row;
foreach(DataRow dr in z)
Console.WriteLine("Account #: {0} Account name: {1}", dr["AccountNumber"], dr["AccountName"]);
Console.WriteLine();
Console.WriteLine("Datatable select");
var y = from row in dt.Select()
where (from x in dt.Select("AccountNumber = " + row["AccountNumber"]) select x).Count() == 1
orderby row["AccountName"]
select row;
foreach (DataRow dr in y)
Console.WriteLine("Account #: {0} Account name: {1}", dr["AccountNumber"], dr["AccountName"]);
With the results printed to the screen, notice that any row with an AccountNumber of '5' is missing, because it wasn't unique. Also notice that in the first example i used the dataTable.Select() to do the ordering, as the ordering is the same irrespective of what rows are removed due to not being unique. The second and third samples will give you an IEnumerable list of rows to work with that you can bind directly to, the first will give you a bunch of groups containing the individual rows.