По сути, вы хотите получить определенные поля из DataTable без жесткого кодирования имен полей.
Следующий код вернет один объект словаря на строку с полями, указанными в вашем массиве. Нет необходимости создавать дополнительные методы расширения или сравнения:
var result = (from row in _dataTable.AsEnumerable()
let projection = from fieldName in fields
select new {Name = fieldName, Value = row[fieldName]}
select projection.ToDictionary(p=>p.Name,p=>p.Value));
Внутренний выбор выбирает нужные значения полей из каждой строки таблицы и сохраняет их в переменной проекции. Внешний выбор преобразует эту переменную в словарь
Вы можете перебрать результат, чтобы получить конкретные поля, подобные этим:
foreach (var row in result)
{
Console.WriteLine(row["field1"]);
}
EDIT:
Приведенный выше код не возвращает различные значения. Можно возвращать различные значения без написания специального компаратора, используя группу по , но код не очень красивый:
var result = (from row in table.AsEnumerable()
let projection = from fieldName in fields
select new { Name = fieldName, Value = row[fieldName] }
group projection by projection.Aggregate((v, p) =>
new {
Name = v.Name + p.Name,
Value = (object)String.Format("{0}{1}", v.Value, p.Value)
}) into g
select g.FirstOrDefault().ToDictionary(p=>p.Name,p=>p.Value));
Агрегат создает новую проекцию, свойства имени и значения которой являются объединением всех полей имени и значения. Результат агрегата используется для группировки всех строк и возврата первой строки каждой группы. Это работает, но определенно ужасно.
Было бы лучше создать простой DictionaryComparer, подобный следующему коду:
public class DictionaryComparer<TKey,TValue>: EqualityComparer<Dictionary<TKey,TValue>>
{
public override bool Equals(Dictionary<TKey, TValue> x, Dictionary<TKey, TValue> y)
{
//True if both sequences of KeyValuePair items are equal
var sequenceEqual = x.SequenceEqual(y);
return sequenceEqual;
}
public override int GetHashCode(Dictionary<TKey, TValue> obj)
{
//Quickly detect differences in size, defer to Equals for dictionaries
//with matching sizes
return obj.Count;
}
}
Это позволяет написать:
var result = (from row in table.AsEnumerable()
let projection = from fieldName in fields
select new {Name = fieldName, Value = row[fieldName]}
select projection.ToDictionary(p=>p.Name,p=>p.Value))
.Distinct(new DictionaryComparer<string, object>());