Reputation: 9225
var qry = from r1 in dtCMS.AsEnumerable() //row count - 416
from r2 in dtEcho.AsEnumerable() //row count - 175
where
r1.Field<string>("Name") == r2.Field<string>("Name")
select r2;
DataTable dt1 = dtEcho.AsEnumerable().Except(qry).CopyToDataTable();
Error:
The source contains no DataRows.
How can I modify the code above so that the comparison will only happen for the rows in r2
?
I would like two functions:
dtEcho
to dtCMS
, and return anything that is in
dtEcho
but not in dtCMS
.dtEcho
to dtCMS
, and return anything that is in
dtCMS
but not in dtEcho
.The code fails if the DataTable I am comparing against has more rows and hence it can't compare.
Upvotes: 0
Views: 124
Reputation: 125197
CopyToDataTable
will throw an InvalidOperationException
if the source sequence does not contain any DataRow
objects:
The source contains no DataRows.
Your code is OK in general and to solve the problem with minimum changes, the only thing that you should change is the way that you create the result.
Instead of using CopyToDataTable
put results in the result table using a for loop. To do so, first you should create a clone of your second table.
var qry = from r1 in table1.AsEnumerable() //row count - 416
from r2 in table2.AsEnumerable() //row count - 175
where
r1.Field<string>("Name") == r2.Field<string>("Name")
select r2;
var dt = table2.Clone();
table2.AsEnumerable().Except(qry).ToList().ForEach(x =>
{
dt.Rows.Add(x);
});
this.dataGridView1.DataSource = dt;
Upvotes: 2
Reputation: 23078
If I got right what you want, the code should look like this:
// setup
var dtCMS = new DataTable();
dtCMS.Columns.Add("ID", typeof(int));
dtCMS.Columns.Add("Name", typeof(String));
for (int i = 0; i < 416; i++)
dtCMS.Rows.Add(i, "Name " + i);
var dtEcho = new DataTable();
dtEcho.Columns.Add("ID", typeof(int));
dtEcho.Columns.Add("Name", typeof(String));
for (int i = 400; i < 575; i++)
dtEcho.Rows.Add(i, "Name " + i);
// convert to enumerables
var cmsEnum = dtCMS.AsEnumerable();
var echoEnum = dtEcho.AsEnumerable();
var CmsMinusEcho = cmsEnum.Where(cms => !echoEnum.Any(echo => echo.Field<String>("Name").Equals(cms.Field<String>("Name"))));
var EchoMinusCms = echoEnum.Where(echo => !cmsEnum.Any(cms => cms.Field<String>("Name").Equals(echo.Field<String>("Name"))));
// get DataTable with check
var CmsMinusEchoDt = CmsMinusEcho.Count() > 0 ? CmsMinusEcho.CopyToDataTable() : null;
var EchoMinusCmsDt = EchoMinusCms.Count() > 0 ? EchoMinusCms.CopyToDataTable() : null;
Upvotes: 1