2015-05-08 4 views
0

У меня есть DataRow, например {"Foo", "Bar"} в соответствующем DataTable с 2 строковыми столбцами. Я хочу, чтобы скопировал эту строку в новый DataTable, который имеет строковые столбцы, 0-е из которых является новым значением, которое я хочу передать. Таким образом, результирующая строка должна выглядеть как {«Мой», «Foo», «Bar»}.DataRow Скопировать значения из другого DataRow с дополнительным столбцом

Промыть, повторите. Другая операция копирования будет выглядеть как {«Боб», «Смит»} => {«Мой», «Боб», «Смит»}.

Я попытался использовать DataRow.ItemArray в массиве Array.Copy() и myDataRow.ItemArray.CopyTo (otherDataRow.ItemArray). Затем я прочитал, что это не сработает, потому что ItemArray имеет вид Read-Only, несмотря на то, что intellisense говорит вам об обратном.

И, конечно, я могу написать свой собственный цикл, чтобы скопировать значения по столбцам, но .. Почему это не встроено в библиотеки или что-то в этом роде?

Пример кода:

DataTable dtDestination = new DataTable(); 
DataTable dtSource = new DataTable(); 

dtSource.Columns.Add("Str1"); 
dtSource.Columns.Add("Str2"); 

dtDestination.Columns.Add("Str0"); 
dtDestination.Columns.Add("Str1"); 
dtDestination.Columns.Add("Str2"); 

dtSource.Rows.Add("Foo", "Bar"); 
dtSource.Rows.Add("Bob", "Smith"); 

foreach (DataRow drSrc in dtSource.Rows) 
{ 
    DataRow drNew = dtDestination.NewRow(); 
    drNew["Str0"] = "My"; 

    //this doesn't work 
    Array.Copy(drSrc.ItemArray, 0, drNew.ItemArray, 1, drSrc.ItemArray.Length); 

    //this doesn't work either 
    drSrc.ItemArray.CopyTo(drNew.ItemArray, 1); 

    //I want to add the "new row" to my destination table, 
    //*WITH* the contents from the source-row plus the "My" value in the 0th column! 
    dtDestination.Rows.Add(drNew); 
} 
+0

Что случилось перебор? 'drNew [1] = drSrc [0]; drNew [2] = drSrc [1] ' – Zer0

+0

Это моя точка ... Я легко могу сделать это с помощью цикла, отлично. Я спрашиваю, почему это не то, что встраивается в рамки, или, по крайней мере, в какую-то библиотеку, на которую можно просто позвонить. – NateJ

+0

Потому что его прямо вперед и легко сделать. Будет работать лучше, чем копирование массива, например. – Zer0

ответ

1

Вы не можете установить значения .ItemArray без SetValue Но вы можете установить сам ItemArray

 DataTable dtDestination = new DataTable(); 
     DataTable dtSource = new DataTable(); 

     dtSource.Columns.Add("Str1"); 
     dtSource.Columns.Add("Str2"); 

     dtDestination.Columns.Add("Str0"); 
     dtDestination.Columns.Add("Str1"); 
     dtDestination.Columns.Add("Str2"); 

     dtSource.Rows.Add("Foo", "Bar"); 
     dtSource.Rows.Add("Bob", "Smith"); 

     foreach (DataRow drSrc in dtSource.Rows) 
     { 
      DataRow drNew = dtDestination.NewRow(); 
      var array = new object[drSrc.ItemArray.Length]; 
      array[0] = "My"; 
      Array.Copy(drSrc.ItemArray, 0, array, 1, drSrc.ItemArray.Length); 
      drNew.ItemArray = array; 
      dtDestination.Rows.Add(drNew); 
     } 

И вы должны добавить Testvalues ​​к Источнику, а не назначения Стол ...

+0

Хороший ответ! Спасибо за уловку при сдаче тестовых значений в dtDestination; Я отредактировал свой вопрос, чтобы поместить их в dtSource. – NateJ

1

Создание метода продления:

public static void CopyValuesFrom(this DataRow me, DataRow copyFrom, int insertIndex = 0, int copyIndex = 0, int count = 0) 
{ 
    if (count == 0) 
     count = Math.Min(copyFrom.ItemArray.Length - copyIndex, me.ItemArray.Length - insertIndex); 
    for (var i = 0; i < count; i++) 
     me[insertIndex + i] = copyFrom[copyIndex + i]; 
} 

Сделайте копию:

drNew.CopyValuesFrom(drSrc, 1); 
+0

Я написал мини-библиотеку (хотя я могу злоупотреблять этим термином), если вы хотите просмотреть мой код, дайте мне знать, что вы думаете - https://dotnetfiddle.net/Widget/AGswyE – NateJ

+0

@NateJ - Это похоже на мой ответ, но менее гибкий.Мало что. Они не являются методами расширения, и вы не можете указать свой собственный счет для копирования. Лично, если вы хотите дважды проверить ввод, я бы бросил более конкретные исключения (например, InvalidOperationException). В этом случае я также проверил бы null и выбросил 'ArgumentNullException'. – Zer0

0

Существует straightfoward способ сделать это, просто использовать ImportRow метод и дополнительно после этого значения подачи дополнительного столбца

 Смежные вопросы

  • Нет связанных вопросов^_^