-1

I have two Datatables

Datatable A; //has a primany key ID
Datatable B; // has a primary key ID

I want the difference between A and B (A minus B). When using except operator in C#, on what parameter does except function? I want the difference between A and B based on the primary key.

sujith karivelil
  • 28,671
  • 6
  • 55
  • 88

2 Answers2

0

The documentation has exactly what you need:

IEqualityComparer

If you want to compare sequences of objects of some custom data type, you have to implement the IEqualityComparer generic interface in a helperclass.

You can compare using you own comparer and use only a column or a set of column.

public class ProductA
{ 
    public string Name { get; set; }
    public int ID { get; set; }
}

public class ProductComparer : IEqualityComparer<ProductA>
{

    public bool Equals(ProductA x, ProductA y)
    {
        //Check whether the objects are the same object. 
        if (Object.ReferenceEquals(x, y)) return true;

        //Check whether the products' properties are equal. 
        return x.ID== y.ID;
    }

    public int GetHashCode(ProductA obj)
    {
        //Get hash code for the ID field. 
        return obj.Code.GetHashCode();
    }
}

enter image description here
SourceA.Except(SourceB) will give you everything that is in source A but not in source B

but
and SourceB.Except(SourceA) will be the opposite.

Or you could be looking for a Full Outter Join!

Community
  • 1
  • 1
Drag and Drop
  • 2,672
  • 3
  • 25
  • 37
  • I understand this. But my question is restricted to datatable, I want the difference based on only one column – Vineet Alampally Dec 12 '17 at 07:46
  • @VineetAlampally, `DataTable` is an object so the exemple is correct here too. But carefull on the visibility of an implementation of a `IEqualityComparer` as every `DataRow` may you it. And the access to `(int)x["Id"]` could throw a nice exception. – Drag and Drop Dec 12 '17 at 12:30
0

Here'c complete code. The rows are compared by Id column (you can see it in RowsComparer's Equals method).

namespace SO
{
    class Program
    {
        static void Main(string[] args)
        {
            var dt1 = new DataTable();
            dt1.Columns.AddRange(new[]
            {
                new DataColumn("Id", typeof(int)),
                new DataColumn("Name", typeof(string)),
                new DataColumn("Age",typeof(string))
            });

            var dt2 = new DataTable();
            dt2.Columns.AddRange(new[]
            {
                new DataColumn("Id", typeof(int)),
                new DataColumn("Name",typeof(string)),
                new DataColumn("Age",typeof(string))
            });

            dt1.Rows.Add(new object[] { 1, "Peter", "20" });
            dt1.Rows.Add(new object[] { 2, "John", "30" });

            dt2.Rows.Add(new object[] { 1, "Peter", "20" });
            dt2.Rows.Add(new object[] { 2, "John", "30" });
            dt2.Rows.Add(new object[] { 3, "Robert", "30" });

            var except = dt2.AsEnumerable().Except(dt1.AsEnumerable(), new RowsComparer());

            foreach (DataRow row in except)
                Console.WriteLine($"Id = {row[0]}, Name = {row[1]}, Age = {row[2]}");
        }

        class RowsComparer : IEqualityComparer<DataRow>
        {
            public bool Equals(DataRow x, DataRow y)
            {
                int id1 = (int)x["Id"];
                int id2 = (int)y["Id"];
                return id1 == id2;
            }

            public int GetHashCode(DataRow obj)
            {
                int hash = obj[0].GetHashCode() + obj[1].GetHashCode() + obj[2].GetHashCode();
                return hash;
            }
        }
    }

}
JohnyL
  • 6,894
  • 3
  • 22
  • 41
  • if equality is based on one field why GetHashCode should behave differently. Has the Hashcode must remain the same for the life time of an object using mutable variable for it look like a bad idea. And Here a `Distinct` will use the Equals overload but Dict will use hash do to have a real Dict you will have to call `Distinct` on it, Weird. – Drag and Drop Dec 12 '17 at 10:55
  • I wonder who down-voted and for what reason? The earlier answer gave OP a general idea, while mine expands in concrete objects. – JohnyL Dec 12 '17 at 10:58
  • earlier answer gave op link to documentation that contains a solid exemple on how to do it. Op just had to scroll now i feel like a plagiarized the doc witha simple copypasta of documenation code with 4 line removed – Drag and Drop Dec 12 '17 at 12:14