我有一组string
说:
String[] Fields=new String[]{RowField,RowField1}
我可以使用以下查询通过指定值来获取值,即查询RowField
和RowField1
:
var Result = (
from x in _dataTable.AsEnumerable()
select new
{
Name = x.Field<object>(RowField),
Name1 = x.Field<object>(RowField1)
})
.Distinct();
但是假设我在Array
中有很多值,比如:
String[] Fields= new String[]
{
RowField,
RowField1,
RowField2,
.......
RowField1000
};
答案 0 :(得分:3)
var Result = (
from x in _dataTable.AsEnumerable()
select (
from y in Fields
select new KeyValuePair<string, object>(y, x))
.ToDictionary())
.Distinct(DictionariesComparer);
您还需要编写自己的.ToDictionary()
扩展方法和DictionariesComparer
方法(因为Dictionary
未实现IEquatable
)。
答案 1 :(得分:2)
实际上,您希望从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));
内部选择从每个表行中选择所需的字段值,并将它们存储在投影变量中。外部选择在Dictionary
中转换此变量您可以迭代结果以获取如下所示的特定字段:
foreach (var row in result)
{
Console.WriteLine(row["field1"]);
}
修改强> 上面的代码不返回不同的值。可以返回不同的值,而无需使用 group by 编写特殊的比较器,但代码不是很漂亮:
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));
Aggregate创建一个新投影,其Name和Value属性是所有name和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>());
答案 2 :(得分:0)
没有foreach linq表达。我通常会创建自己的扩展方法
有些事情:
public static void Foreach<T>(this IEnumerable<T> items, Action<T> action)
{
foreach(T t in items)
{
action(t);
}
}
但是要注意你是否打算在Linq2SQL上使用它,因为它可能会产生大量的db命中!