Объедините несколько DataRow в один DataRow - PullRequest
0 голосов
/ 24 февраля 2009

Я пишу это в C #, используя .NET 3.5. У меня есть объект System.Data.DataSet с одним DataTable, который использует следующую схему:

Id      :  uint
AddressA:  string
AddressB:  string
Bytes   :  uint

Когда я запускаю свое приложение, скажем, DataTable заполняется следующим:

1   192.168.0.1   192.168.0.10   300
2   192.168.0.1   192.168.0.20   400
3   192.168.0.1   192.168.0.30   300
4   10.152.0.13   167.10.2.187    80

Я бы хотел иметь возможность запросить этот DataTable, где AddressA уникален, а столбец Bytes суммируется (я не уверен, что говорю правильно). По сути, я бы хотел получить следующий результат:

1   192.168.0.1   1000
2   10.152.0.13     80

В конечном итоге я хочу получить этот результат в DataTable, который можно привязать к DataGrid, и мне нужно обновлять / восстанавливать этот результат каждые 5 секунд или около того.

Как мне это сделать? Метод DataTable.Select ()? Если да, то как выглядит запрос? Есть ли альтернативный / лучший способ достичь моей цели?

РЕДАКТИРОВАТЬ: У меня нет базы данных. Я просто использую DataSet в памяти для хранения данных, поэтому чистое решение SQL здесь не подойдет. Я пытаюсь понять, как это сделать в самом DataSet.

Ответы [ 4 ]

4 голосов
/ 25 февраля 2009

Для удобства чтения (и потому что мне это нравится), я бы попробовал использовать LINQ:

var aggregatedAddresses = from DataRow row in dt.Rows
group row by row["AddressA"] into g
select new {
    Address = g.Key,
    Byte = g.Sum(row => (uint)row["Bytes"])
};

int i = 1;
foreach(var row in aggregatedAddresses)
{
    result.Rows.Add(i++, row.Address, row.Byte);
}

Если проблема с производительностью обнаружена с помощью решения LINQ, я бы пошел с ручным решением, суммируя строки в цикле над исходной таблицей и вставляя их в таблицу результатов.

Вы также можете привязать агрегатные адреса непосредственно к сетке, а не помещать их в таблицу данных.

3 голосов
/ 24 февраля 2009

наиболее эффективным решением было бы сделать сумму в SQL напрямую

выберите адрес A, SUM (в байтах) из ... группы по адресу A

2 голосов
/ 25 февраля 2009

Я также согласен со Стивеном, что делать это на стороне сервера - лучший вариант. Однако если вы используете .NET 3.5, вам не нужно проходить через то, что предлагает Rune. Скорее используйте методы расширения для наборов данных, чтобы помочь запросить и суммировать значения.

Затем вы можете легко сопоставить его с анонимным типом, который вы можете установить в качестве источника данных для вашей сетки (при условии, что вы не разрешаете редактирование этого, что я не вижу, как вы можете, поскольку вы агрегируете данные).

1 голос
/ 25 февраля 2009

Я согласен со Стивеном, что лучший способ сделать это - сделать это в базе данных. Но если это не вариант, вы можете попробовать следующее:

  • Создайте новую таблицу данных и добавьте нужные столбцы вручную, используя DataTable.Columns.Add (name, datatype)
  • Пройдите первую коллекцию строк данных и создайте для каждой строки новую строку в новой таблице данных, используя DataTable.NewRow ()
  • Скопировать значения столбцов из первой таблицы в новую строку
  • Найдите соответствующую строку в другой таблице данных, используя Select (), и скопируйте окончательное значение в новую строку данных
  • Добавить строку в новую таблицу данных, используя DataTable.Rows.Add (newRow)

Это даст вам новую таблицу данных, содержащую объединенные данные из двух таблиц. Это не будет очень быстро, но если у вас нет огромных объемов данных, вероятно, это будет достаточно быстро. Но старайтесь избегать выполнения LIKE-запроса в Select, потому что он медленный.

Одна возможная оптимизация была бы возможна, если бы обе таблицы содержали строки с одинаковыми первичными ключами. Затем вы можете сортировать обе таблицы и проходить по ним, выбирая обе строки данных, используя их индекс массива. Это избавит вас от вызова Select.

...