0

if i have two datatables :

DT1 & DT2

How to check if the first one contains the second one , i mean that the same rows of DT2 is in the DT1.

Anyname Donotcare
  • 11,113
  • 66
  • 219
  • 392
  • 1
    Must all row's fields match with the same(what primary key?) row's fields of the other DataTable? – Tim Schmelter Jun 18 '12 at 14:05
  • this post has nothing to do with asp.net or linq. – Jason Meckley Jun 18 '12 at 14:05
  • care to explain how comparing the data in 2 data tables has anything to do with linq or asp.net? put another way. do you think the approach would change whether you use linq or not, or whether the UI is a webpage or rich client? – Jason Meckley Jun 18 '12 at 14:13
  • it is already discussed in following link http://stackoverflow.com/questions/6833454/c-sharp-merge-two-datatables-where-rows-are-duplicate – SSK .NET PRO Jun 18 '12 at 14:15
  • @JasonMeckley :thanks a lot , but when i insist to put the `linq` and `asp.net` tags i have a reason . could u take a look at the answer please . – Anyname Donotcare Jun 18 '12 at 14:56
  • just because you have a reason, doesn't make it correct. it's misleading to add these tags when your problem isn't directly related to either of these concepts/frameworks/environments. – Jason Meckley Jun 18 '12 at 15:04
  • I'm sorry ,if i made any confusion ,but at the end , the `Linq` is an important part of the answer. – Anyname Donotcare Jun 18 '12 at 15:15

3 Answers3

3

loop through the tables and comapare fields (hopefully just the IDs). there are a number of ways to do this depending on how your datatables are structured.

Jason Meckley
  • 7,589
  • 1
  • 24
  • 45
2

My question: "Must all row's fields match with the same row's fields of the other DataTable?"

Your answer: "no just the id"

You can first check if both DataTables are null or both have the same row-count. Then you can use LINQ to determine if both have the same IDs using Enumerable.Except:

var dt1IDs = DT1.AsEnumerable().Select(r => r.Field<int>("id"));
var dt2IDs = DT2.AsEnumerable().Select(r => r.Field<int>("id"));
var diff = dt1IDs.Except(dt2IDs);
var equal = DT1.Rows.Count == DT2.Rows.Count && !diff.Any();

Explanation: diff.Any() returns true when there's at least one id in DT1 that is not in DT2.

Edit: If the ID is not unique and might repeat you need to check whether all ID's in DT1 are also in DT2 and all IDs of DT2 are in DT1:

var DT1InDT2 = dt1IDs.Except(dt2IDs);
var DT2InDT1 = dt2IDs.Except(dt1IDs);
var equal = DT1.Rows.Count == DT2.Rows.Count && !DT1InDT2.Any() && !DT2InDT1.Any();

This query is efficient anyway.


Edit2: I've just seen that i've misunderstood your requiremnet a little bit. You only want to know if the first table contains the second, not vice-versa.

var DT2IdNotInDT1 = dt2IDs.Except(dt1IDs);
var equal = !DT2IdNotInDT1.Any();
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • I try it the first ids(200,300,146) the second ids (200,300) so it should return true not false but it return `false` – Anyname Donotcare Jun 18 '12 at 14:38
  • no the ids are unique but should i rely on the diff only ?? please check the above comment – Anyname Donotcare Jun 18 '12 at 14:42
  • 1
    @just_name: Of course it returns false since the first table has 3 records whereas the second has only two. – Tim Schmelter Jun 18 '12 at 14:42
  • then i should rely on diff only because my question is check that the first datatable contain the whole second one – Anyname Donotcare Jun 18 '12 at 14:43
  • 1
    @just_name: I've just seen that i've misunderstood your requiremnet a little bit. You only want to know if the first table contains the second, not vice-versa. Wait a moment, i'll edit my answer. – Tim Schmelter Jun 18 '12 at 14:46
  • you do realize that linq is looping through all of the records in the both tables using a foreach loop. the syntax is compact and expressive, but don't be fooled that it's faster/effecient/etc. it's expressive and, like most tools, can actually be dangerous when used incorrectly. – Jason Meckley Jun 19 '12 at 11:22
  • @JasonMeckley: It's just looping through the `IEnumerable` (the ID's) of both DataTables and uses a `HashSet` internally for the second sequence passed in - that allows it to look up elements in O(1) while iterating over the first sequence to filter out elements that are contained in the second sequence. So it's not only short and elegant but also very efficient. – Tim Schmelter Jun 19 '12 at 11:36
  • @TimSchmelter I wasn't implying this is not efficient. only that the OP asked a question, but expected a specific answer: "linq". – Jason Meckley Jun 19 '12 at 11:40
0

you can use Intersect operator

var intersect = DT2.AsEnumerable().Intersect(DT1.AsEnumerable(), DataRowComparer.Default);

Aghilas Yakoub
  • 28,516
  • 5
  • 46
  • 51