2017-10-23 1 views
0

Ich habe zwei DataTable s: dt1 und dt2.Merge Spalten von zwei DataTables mit Linq

dt1:

ID  | Name  | Address | QTY 
-------+----------+---------+----- 
A1  | Dog  | C1  | 272  
A2  | Cat  | C3  | 235  
A3  | Chicken | C2  | 254  
A4  | Mouse | C4  | 259 
A5  | Pig  | C5  | 233 

dt2:

ID  | Name  | Address | QTY MAX 
-------+----------+---------+-------- 
A1  | Dog  | C1  | 250  
A2  | Cat  | C3  | 200  
A3  | Chicken | C2  | 300  
A6  | Rabbit | C6  | 350  

Aber, ich will dt1 und dt2 zu dt3 wie unten fusionieren:

ID  | Name  | Address | QTY | QTY MAX 
-------+----------+---------+-------+-------- 
A1  | Dog  | C1  | 272 | 250 
A2  | Cat  | C3  | 235 | 200 
A3  | Chicken | C2  | 254 | 300 
A4  | Mouse | C4  | 259 | 0 
A5  | Pig  | C5  | 233 | 0 
A6  | Rabbit | C6  | 0  | 350 

Kann mir jemand helfen?

Antwort

2

Diese Lösung ist kein Lösung, wie Sie einfach DataTable.Merge & DataTable.PrimaryKey bekommen die gewünschte Ausgabe nutzen könnten. Hier

ist ein Dummy-Beispiel, das Sie verwenden können:

var dt1 = new DataTable(); 
var p1 = dt1.Columns.Add("a", typeof(int)); //Use this to add Primary Key constraint 
dt1.Columns.Add("b"); 
dt1.Columns.Add("c"); 
dt1.Rows.Add("1", "apple", "10"); 
dt1.Rows.Add("2", "mango", "20"); 
dt1.Rows.Add("3", "orange", "30"); 
dt1.Rows.Add("4", "banana", "40"); 
dt1.PrimaryKey = new DataColumn[] { p1 }; //This removes duplication of rows 

var dt2 = new DataTable(); 
var p2 = dt2.Columns.Add("a", typeof(int)); //Use this to add Primary Key constraint   
dt2.Columns.Add("b"); 
dt2.Columns.Add("d"); 
dt2.Rows.Add("1", "apple", "50"); 
dt2.Rows.Add("2", "mango", "60"); 
dt2.Rows.Add("3", "orange", "70"); 
dt2.Rows.Add("5", "grapes", "80"); 
dt2.PrimaryKey = new DataColumn[] { p2 }; //This removes duplication of rows 

var dt3 = dt1.Copy(); 
dt3.Merge(dt2); // Merge here merges the values from both provided DataTables 

Unter Ihrer Frage in Betracht:

var dt1 = new DataTable(); 
var p1 = dt1.Columns.Add("ID", typeof(string)); 
dt1.Columns.Add("Name", typeof(string)); 
dt1.Columns.Add("Address", typeof(string)); 
dt1.Columns.Add("Qty", typeof(int)); 
dt1.Columns["Qty"].DefaultValue = 0; //Setting default value 
dt1.Rows.Add("A1", "Dog", "C1", 100); 
dt1.Rows.Add("A2", "Cat", "C3", 200); 
dt1.Rows.Add("A3", "Chicken", "C2", 300); 
dt1.Rows.Add("A4", "Mouse", "C4", 400); 
dt1.Rows.Add("A5", "Pig", "C5", 500); 
dt1.PrimaryKey = new DataColumn[] { p1 }; 

var dt2 = new DataTable(); 
var p2 = dt2.Columns.Add("ID", typeof(string)); 
dt2.Columns.Add("Name", typeof(string)); 
dt2.Columns.Add("Address", typeof(string)); 
dt2.Columns.Add("Qty Max", typeof(int)); 
dt2.Columns["Qty Max"].DefaultValue = 0; //Setting default value 
dt2.Rows.Add("A1", "Dog", "C1", 600); 
dt2.Rows.Add("A2", "Cat", "C3", 700); 
dt2.Rows.Add("A3", "Chicken", "C2", 800); 
dt2.Rows.Add("A6", "Rabbit", "C6", 900); 
dt2.PrimaryKey = new DataColumn[] { p2 }; 

var dt3 = dt1.Copy(); 
dt3.Merge(dt2); 

Ausgang:

enter image description here


Danke @ shA.t, dass vorgeschlagen wird, DataColumn.DefaultValue einzuschließen, so dass leere Zellen durch 0 ersetzt werden können. Auch seine Antwort scheint Funktionen zu enthalten, die ich denke, was Sie suchen!

+0

Nizza und setzen '0' Werte Für 'QTY' und' QTY Max' müssen Sie folgendes verwenden: 'var q1 = dt1.Columns.Add (" Qty ", typeof (int)); q1.DefaultValue = 0; '-HTH;). –

+0

Vielen Dank für Ihren Kommentar @o_O, diese Antwort gut für mich – hung34k

2

Wenn Ihr DataTable s nicht Primärschlüssel haben und Sie nicht können oder wollen nicht diejenigen DataTable s ändern Sie einen Code wie folgt verwenden können:

// At first you need to define your result `DataTable` 
// So make it by cloning from first `DataTable` 
var dt3 = dt1.Clone(); 
// Then add extra columns to it 
dt3.Columns.Add("Qty Max", typeof(int)); 

// Second, you need to add rows of first `DataTable` 
foreach (DataRow row in dt1.Rows) 
{ 
    // When you don't have a primary key you need a code like this to find same rows: 
    var dt2Row = dt2.Rows.OfType<DataRow>().SingleOrDefault(w => w["ID"].Equals(row["ID"])); 
    var qtyMax = dt2Row?["Qty Max"] ?? 0; // Here I set default value to `0` 

    dt3.Rows.Add(row["ID"], row["Name"], row["Address"], row["Qty"], qtyMax); 
} 

// Third, you need to add rows of second `DataTable` that is not in first 
var dt2OnlyRows = 
    dt2.Rows.OfType<DataRow>().Where(w => dt1.Rows.OfType<DataRow>().All(x => x["ID"] != w["ID"])); 
foreach (var row in dt2OnlyRows) 
{ 
    dt3.Rows.Add(row["ID"], row["Name"], row["Address"], 0, row["Qty Max"]); 
} 
+0

Vielen Dank @ shA.t für Ihren Kommentar, auf diese Weise für mich richtig, aber dt1 haben etwa 10k Zeilen und dt2 haben etwa 20k Zeile und sie werden in Zukunft erhöhen. Also ich suche nach besserer Antwort – hung34k

+0

Also, ich hoffe, Sie haben Primärschlüssel und können @ o_O's Antwort verwenden;). –

Verwandte Themen