Как получить только самые новые записи с одинаковым идентификатором в DataTable? - PullRequest
3 голосов
/ 30 мая 2011

У меня есть следующее:

DataTable table = new DataTable();
table.Columns.Add("id", typeof(string));
table.Columns.Add("date", typeof(DateTime));

DateTime date1 = new DateTime(2008, 3, 1, 7, 0, 0);
DateTime date2 = new DateTime(2007, 3, 1, 7, 0, 0);
DateTime date3 = new DateTime(2006, 3, 1, 7, 0, 0);

table.Rows.Add("123", date1);
table.Rows.Add("123", date2);
table.Rows.Add("ABC", date3);

Я хочу запустить действие, которое удалит все строки с тем же идентификатором, что и другая строка, и сохранит только ту, у которой самая новая дата.

В этом небольшом примере в начале у меня есть:

123 2008...
123 2007...
ABC 2006...

После действия должно быть:

123 2008...
ABC 2006...

Как я могу это понять?

(это лишь небольшой пример, мои реальные данные намного больше)

Ответы [ 4 ]

2 голосов
/ 30 мая 2011

Если вы не можете напрямую фильтровать данные в источнике данных (= настроить запрос SQL), вы можете удалить строки, используя следующий код:

var multiDates = from dr in table.AsEnumerable()
                 group dr by dr.Field<string>("id") into grp
                 where grp.Count() > 1
                 select grp.OrderByDescending(gr => gr.Field<DateTime>("date"));

var toDelete = multiDates
    .SelectMany(rows => rows.Skip(1))
    .ToArray();

foreach (var row in toDelete)
    row.Delete();

table.AcceptChanges();
0 голосов
/ 30 мая 2011

Вот одна альтернатива

 var rowsToDelete = 
              (from outer in table.AsEnumerable()
              where !(from inner in table.AsEnumerable()
                    group inner by inner.Field<string>("id") into grp
                    where grp.Key == outer.Field<string>("id") &&
                          grp.Max (g => g.Field<DateTime>("date")) == outer.Field<DateTime>("date")
                    select grp.Key).Any()
              select outer).ToList();

foreach (var row in rowsToDelete) 
   row.Delete();
table.AcceptChanges();
0 голосов
/ 30 мая 2011

Если вы хотите проверить после вставки всех данных, вы можете отсортировать данные DataTable с помощью DataView, перечислить все строки, проверить наличие дубликатов и удалить их.

DataView dv = new DataView(DATA_TABLE, "", "ID, Date DESC", DataViewRowState.None);
for (int i = 1; i < dv.Count; i++)
{
    if (dv[i - 1].Row["ID"] == dv[i].Row["ID"])
    {
       dv[i].Delete();
       i--;
    }
 }

В случае, если выможете проверять вставку, использовать какой-то тип EndEdit_Event для проверки дубликатов идентификаторов

Вы можете даже рассмотреть возможность использования некоторого вида dataSource (ArrayList, List, DataSet aso) и использовать ограничения или некоторую проверку businessLogic.

0 голосов
/ 30 мая 2011

У вас может быть запрос linq для отдельного идентификатора поля, как показано ниже

var MyQry=(from P5 in table.AsEnumerable() select P5["id"]).Distinct().ToList();
for (int O1 = 0; O1 < MyQry.Count; O1++)
{
     richTextBox1.Text = MyQry[O1].ToString();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...