using System.Collections.Generic;
public static void Main()
var rightDt = new DataTable();
rightDt.Columns.Add("Foo");
rightDt.Columns.Add("Bar", typeof(int));
rightDt.Columns.Add("Baz");
rightDt.Rows.Add("John", 1, "R");
rightDt.Rows.Add("Mark", 2, "R");
rightDt.Rows.Add("Luke", 3, "R");
var leftDt = new DataTable();
leftDt.Columns.Add("Wit");
leftDt.Columns.Add("Woo", typeof(int));
leftDt.Columns.Add("Baz");
leftDt.Rows.Add("Mark", 2, "L");
leftDt.Rows.Add("Luke", 3, "R");
leftDt.Rows.Add("Mary", 4, "L");
var allKeys = new HashSet<(string, int)>();
var rIndex = new Dictionary<(string, int), DataRow>();
foreach(DataRow r in rightDt.Rows){
var key = (r.Field<string>("Foo"), r.Field<int>("Bar"));
var lIndex = new Dictionary<(string, int), DataRow>();
foreach(DataRow r in leftDt.Rows){
var key = (r.Field<string>("Wit"), r.Field<int>("Woo"));
foreach(var k in allKeys){
var inL = lIndex.ContainsKey(k);
var inR = rIndex.ContainsKey(k);
var updateRo = lIndex[k];
var toUpdate = rIndex[k];
if(toUpdate["Baz"].ToString() == updateRo["Baz"].ToString())
Console.WriteLine("dont update" + k.ToString() + " because other data is same");
Console.WriteLine("update" + k.ToString());
var insertRo = lIndex[k];
Console.WriteLine("insert" + k.ToString());
var deleteRo = rIndex[k];
Console.WriteLine("delete" + k.ToString());