Лучший способ объединить два отсортированных DataTables, без повторяющихся строк? (C#) - PullRequest
0 голосов
/ 04 мая 2020

У меня есть две DataTables (DataTableA и DataTableB), например, следующие: (Предположим, что каждая строка является каждой строкой данных. Также я добавил подчеркивание, чтобы оно выглядело хорошо. Подчеркивания не включены в фактические данные.

DataTableA

CategoryA | *blank* | *blank* | *blank* | ... 
Michael __|  24  __ | _31    _| _ 21_   | ... 
Tony  ____| _29  __ | _28    _| _ 19_   | ... 
CategoryB | *blank* | *blank* | *blank* | ... 
John  ____| _12  __ | _31    _| _ 25_   | ... 
CategoryC | *blank* | *blank* | *blank* | ... 
...

DataTableB

CategoryA   | *blank* | *blank* | *blank* | ... 
Jessica ____| _35  __ | _35 _   | _ 35_   | ... 
CategoryB   | *blank* | *blank* | *blank* | ... 
Michaela  __| _10  __ | _11 _   | _ 12_   | ... 
Miranda   __| 25   __ | _25 _   | _ 25_   | ... 
CategoryC   | *blank* | *blank* | *blank* | ... 
...

Теперь мне нужно объединить их и конечный продукт должно быть как:

DataTable C

CategoryA   | *blank* | *blank* | *blank* | ... 
Michael   __| 24  __  | _31 _   | _ 21_   | ... 
Tony    ____| _29  __ | _28 _   | _ 19_   | ... 
Jessica ____| _35  __ | _35 _   | _ 35_   | ... 
CategoryB   | *blank* | *blank* | *blank* | ... 
John ____   | _12  __ | _31 _   | _ 25_   | ... 
Michaela __ | _10  __ | _11 _   | _ 12_   | ... 
Miranda __  | 25  __  | _25 _   | _ 25_   | ... 
CategoryC   | *blank* | *blank* | *blank* | ... 

Как вы можете видеть, данные из DataTableB должны следовать за данными DataTableA. строки категорий не должны дублироваться.

Я объединил их с помощью метода DataTable.Merge (), но теперь он выглядит как две таблицы DataTable, только что скомбинированные вплотную, и также имеет дублированные строки категорий. Я хочу как-то использовать метод .Join, чтобы отсортировать их и собрать данные вместе, но я не совсем уверен, как go об этом.

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

1 Ответ

1 голос
/ 04 мая 2020

По моим соображениям, отмеченным в комментариях, если вы застряли с этими данными, как они есть (а если нет, пожалуйста, измените их сейчас, прежде чем начинать складывать больше кода поверх этой шаткой основы), тогда вы ' Мне нужно будет реализовать несколько пользовательских слияний (это пример того, почему я говорю: «Не делайте этого, потому что эта плохая структура данных уже вызывает у вас достаточно головной боли, так как вам приходилось приходить на SO и спрашивать об этом»). ) вдоль строк:

var d = new Dictionary<string, List<DataRow>>();
string currentCat = "Category A";

FillDictionaryFromDataTable(d, table1);
FillDictionaryFromDataTable(d, table2);


public void FillDictionaryFromDataTable(Dictionary<string, List<DataRow>> d, DataTable dt) {

  foreach(DataRow r in dt.Rows){

    string x = r[0].ToString();
    if(x.StartsWith("Category"))
      currentCat = x;
    else {
      if(!d.ContainsKey(currentCat))
        d[currentCat] = new List<DataRow>();

      d[currentCat].Add(r);
    }
  }
}

Теперь у вас есть словарь списков DataRow. Вы не можете добавить эти строки в новую таблицу, потому что они уже принадлежат таблице; вам нужно их клонировать

DataTable x = table1.Clone();//make structure but not data
foreach(string key in d.Keys.OrderBy(k => k)){

  var catRo = x.NewRow();
  catRo[0] = key;
  x.Rows.Add(catRo);

  foreach(DataRow ro in d[key]) //a List<Datarow>
    x.Rows.Add(ro.ItemArray); //make a new row that clones this row's values
}

Фу

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...