Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare DataRow collection to List<T>

I have a List<string> and I have a DataTable.

One of the columns in a DataRow is ID. The List holds instances of this ID.

The DataTable gets populated on a Timer.

I want to return items from the List that are not in the DataTable into another list.

like image 763
Jon Avatar asked Jan 05 '10 11:01

Jon


People also ask

Can we convert DataTable to list?

There are the following 3 ways to convert a DataTable to a List. Using a Loop. Using LINQ. Using a Generic Method.

What is DataRow and DataColumn in C#?

The DataRow object represents a table row, and the DataColumn object represents a column of the table. The first step to working with these three objects is to create a data table schema, which is defined by the DataColumnCollection object.

What is DataRowCollection?

The DataRowCollection is a major component of the DataTable. While the DataColumnCollection defines the schema of the table, the DataRowCollection contains the actual data for the table, where each DataRow in the DataRowCollection represents a single row.

How do you create a DataRowCollection?

To create a new DataRow, you must use the NewRow method of the DataTable class. When you use the NewRow method, a new DataRow object is returned using the schema of parent DataTable. After you create the DataRow object and set the values for each of its columns, use the Add method to add the object to the collection.


3 Answers

You will want to do something like this

var tableIds = table.Rows.Cast<DataRow>().Select(row => row["ID"].ToString());

var listIds = new List<string> {"1", "2", "3"};

return listIds.Except(tableIds).ToList();

You can cast the rows in the data table to be an IEnumerable collection and then select the "ID" column value from each of them. You can then use the Enumerable.Except extension method to get all of the values from the List that are not in the collection you just made.

If you need to get the values that are in the table but not the list, just reverse listIds and tableIds.

like image 107
bdowden Avatar answered Nov 01 '22 14:11

bdowden


If your table was something like that:

DataTable dt = new DataTable();
dt.Columns.Add("ID");
DataRow dr = dt.NewRow();
dt.PrimaryKey = new DataColumn[] {dt.Columns[0]};
dr["ID"] = "1";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["ID"] = "2";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["ID"] = "3";
dt.Rows.Add(dr);

and the list was something like this:

List<string> ls = new List<string>{"1","2","4"};

we could get the items found in the list and not in the datatable this way:

var v = from r in ls
                where !dt.Rows.Contains(r)
                select r;
        v.ToList();
like image 21
Mostafa Elmoghazi Avatar answered Nov 01 '22 15:11

Mostafa Elmoghazi


With reasonable efficiency via HashSet<T> (and noting that the fastest way to get data out of a DataRow is via the DataColumn indexer):

        HashSet<int> ids = new HashSet<int>();
        DataColumn col = table.Columns["ID"];
        foreach (DataRow row in table.Rows)
        {
            ids.Add((int)row[col]);
        }
        var missing = list.Where(item => !ids.Contains(item.ID)).ToList();
like image 1
Marc Gravell Avatar answered Nov 01 '22 15:11

Marc Gravell