2013-08-08 6 views
3

Я обновляю некоторое наследие, которое имеет таблицу, содержащую только одну строку. Я хочу преобразовать его в IList. Идея заключается в том, что первым свойством IFoo является Name, которое будет именем столбца из таблицы, а второе, если Value, которое является значением столбца.Преобразование DataTable в IList

/// <summary> 
/// Name = Column Name 
/// </summary> 
String Name { get; set; } 
/// <summary> 
/// Value = Column Value 
/// </summary> 
String Value { get; set; } 

Данные могут выглядеть это

Foo1  Foo2  Foo3 Foo4  Foo5 

xyz  zyx  abc  def  ghi 

И будет:

Foo1, xyz 

Foo2, zyx 

Foo3, abc 

Foo4, def 

Foo5, ghi 

Я не совсем уверен, как это сделать. Похоже, для этого может понадобиться запрос linq. Любая помощь будет оценена по достоинству.

Рхонда

+0

Почему не 'IDictionary' так как вы по существу воссоздавая пару ключевых значений? –

+0

Что вы пробовали? –

+0

IDictionary будет работать. Все еще не совсем уверен, как его кодировать. – Rhonda

ответ

4

Возможно (работает также, если таблица содержит несколько строк):

IList<Foo> data = table.AsEnumerable() 
    .SelectMany(r => table.Columns.Cast<DataColumn>() 
     .Select(col => new Foo 
     { 
      Name = col.ColumnName, 
      Value = r.IsNull(col) ? null : r[col].ToString() 
     })) 
    .ToList(); 
+0

+1 хороший подход. но это дает мне ошибку - имя «r» не существует в текущем контексте. –

+0

'r' - это DataRow. Я тестировал код, и он работает (для меня). Компилятор распознает AsEnumeble? В противном случае вам нужно сначала добавить ссылку на DataTableExtensions.dll. –

+0

Да, я вижу, что r должна быть текущей строкой, а AsEnumerable() работает, но все равно получена ошибка. Я пробовал его в интерактивном режиме Roslyn C#, возможно, так оно и есть. Я проверю его позже в коде C#. –

0

Похоже, классический SQL columns to rows task. Я добавил столбец ID, так что вы можете использовать этот запрос для более одной строки:

var dt = new DataTable(); 
dt.Columns.Add("ID"); 
dt.Columns.Add("Foo1"); 
dt.Columns.Add("Foo2"); 
dt.Rows.Add(1, "xyz", "abc"); 
dt.Rows.Add(2, "cds", "tgf"); 

var q = from row in dt.Rows.Cast<DataRow>() 
     from col in dt.Columns.Cast<DataColumn>() 
     select new { 
      ID = row["ID"], 
      Name = col.ColumnName, 
      Value = row.IsNull(col) ? null : row[col] 
     }; 
q.ToList() 

ID, Name, Value 
1 Foo1 xyz 
1 Foo2 abc 
2 Foo1 cds 
2 Foo2 tgf 

или, если вы хотите создать словарь

q.ToDictionary(x => new { x.ID, x.Name}, x => x.Value) 
Смежные вопросы