我最初提出呼籲與preserveChanges = true的合併()過載,但如果DS2已經排指示其與DS1的不同規定,只適用。正如你在你的問題中所說的,那就是你需要完成的。那麼,算法?這裏有兩個:乾淨,簡單,明顯的方式;並改編爲sort-merge join。周圍有檢查DS2的每一行沒辦法,但第二算法試圖減少預期的數據將被下令DS1搜索量。
1)簡單,乾淨,明顯的;使用DataRowCollection.Find(pk)和object []。SequenceEqual()。每個表中都需要一個主鍵,但不需要排序數據,主鍵的類型也不重要。
for (int i = 0; i < ds2.Tables.Count; i++)
{
foreach (DataRow dr in ds2.Tables[i].Rows)
{
DataRow drOrig = ds1.Tables[i].Rows.Find(dr[0]);
if (drOrig != null)
{
if (!drOrig.ItemArray.SequenceEqual(dr.ItemArray))
{
dr.SetModified();
}
}
else
{
dr.SetAdded();
}
}
}
ds1.Merge(ds2);
2)粗砂,混亂;仍然使用object []。SequenceEqual()。數據必須是有序的,儘管'pk'/行標識符不必是唯一的。但是,它的類型必須爲每個單獨的表格所知,並且如果類型不同,則不能簡單地遍歷表格。
// Assuming first column of each table is int, primary key; and that all data are ordered by pk.
for (int i = 0; i < ds2.Tables.Count; i++)
{
int indexDs1 = 0
int indexDs2 = 0;
DataRow nextDs1Row = ds1.Tables[i].Rows[indexDs1];
DataRow nextDs2Row = ds2.Tables[i].Rows[indexDs2];
int nextDs1Pk = (int)nextDs1Row[0];
int nextDs2Pk = (int)nextDs2Row[0];
while ((indexDs1 < ds1.Tables[i].Rows.Count) && (indexDs2 < ds2.Tables[i].Rows.Count))
{
if (nextDs1Pk == nextDs2Pk)
{
// Set row state to modified if any differences exist.
if (!nextDs1Row.ItemArray.SequenceEqual(nextDs2Row.ItemArray))
{
nextDs2Row.SetModified();
}
// Advance both iterators by one row.
indexDs1++;
if (indexDs1 < ds1.Tables[i].Rows.Count)
{
nextDs1Row = ds1.Tables[i].Rows[indexDs1];
nextDs1Pk = (int)nextDs1Row[0];
}
indexDs2++;
if (indexDs2 < ds2.Tables[i].Rows.Count)
{
nextDs2Row = ds2.Tables[i].Rows[indexDs2];
nextDs2Pk = (int)nextDs2Row[0];
}
}
else if (nextDs1Pk < nextDs2Pk)
{
// Advance through ds1, doing nothing, until the next pk of ds2 is reached.
do
{
indexDs1++;
if (indexDs1 < ds1.Tables[i].Rows.Count)
{
nextDs1Row = ds1.Tables[i].Rows[indexDs1];
nextDs1Pk = (int)nextDs1Row[0];
}
else
{
break;
}
} while (nextDs1Pk < nextDs2Pk);
}
else //nextDs1Pk > nextDs2Pk
{
// Advance through ds2, setting row state to added, until the next pk of ds1 is reached.
do
{
nextDs2Row.SetAdded();
indexDs2++;
if (indexDs2 < ds2.Tables[i].Rows.Count)
{
nextDs2Row = ds2.Tables[i].Rows[indexDs2];
nextDs2Pk = (int)nextDs2Row[0];
}
else
{
break;
}
} while (nextDs1Pk > nextDs2Pk);
}
}
}
如果你的機器多任務好,你並不需要強制執行的設定各表的外鍵約束,我會設置每個表的行分析作爲一個單獨的任務,開始他們都在並行,然後在任務完成時將表格逐一合併。如果這足以使算法1符合您的要求,我會以簡單的名義與它一起使用。它使用find()和SequenceEqual()方法可能是高度優化和算法2並沒有在我的測試更快的執行。如果兩者都不夠快,並且您對數據有所瞭解,則可以改進SequenceEqual()。
是我真正嘗試過了,仍然沒有工作。我會再試一次。 – VoltaicShock 2011-04-05 18:00:45
@Terry你說的沒錯,在DS2的行狀態將需要已經被標記爲工作。我用兩種可能的算法修改了這個答案,並將其作爲一個社區維基。希望其他一些讀者可以改進其中一個足以滿足您的需求。 – Kimberly 2011-04-06 04:41:45