我需要对 DataTable 运行 LINQ 查询以使用多个列获取不同的值。如果我事先知道我需要选择的列,我可以使用来自 David Hoarser 的答案 Select distinct rows from datatable in Linq :
var distinctValues = dsValues.AsEnumerable()
.Select(row => new {
attribute1_name = row.Field<string>("attribute1_name"),
attribute2_name = row.Field<string>("attribute2_name")
})
.Distinct();
但是,在我的例子中,我有需要在对象列表中选择的列名:
public class PC{
public string Name{get;set;}
public string NumFormat{get;set}
}
List<PC>cols=new List<PC>();
cols.AddRange(new PC[]{new PC{Name="FullName",NumFormat=""},
{new PC{Name="Salary",NumFormat="$ #,##0"}});
我可以使用上面 David 的示例来构建 select 语句:
var distinctValues = dsValues.AsEnumerable()
.Select(row => new {
attribute1_name = row.Field<string>(cols[0].Name),
attribute2_name = row.Field<string>(cols[1].Name)
})
.Distinct();
但这行不通,因为我不知道我需要选择多少列,因为 cols 列表可能会有所不同。我如何遍历列列表来构建我的 Select 语句以最终获得我的 Distinct 值?
最佳答案
您可以为该任务实现自定义 IEqualityComparer
class DataRowComparer : IEqualityComparer<DataRow>
{
private readonly List<string> _columns = new List<string>();
public DataRowComparer(DataColumnCollection cols)
{
foreach (DataColumn col in cols)
{
_columns.Add(col.ColumnName);
}
}
public bool Equals(DataRow x, DataRow y)
{
foreach (var column in _columns)
{
if (!IsEqual(x, y, column))
return false;
}
return true;
}
public int GetHashCode(DataRow obj)
{
unchecked
{
var hash = 19;
foreach (var column in _columns)
{
hash = hash*31 + (obj[column] == null ? 0 : obj[column].GetHashCode());
}
return hash;
}
}
private static bool IsEqual(DataRow x, DataRow y, string column)
{
if (x[column] == null && y[column] == null)
return true;
if (x[column] == null || y[column] == null)
return false;
return x[column].Equals(y[column]);
}
}
用法
var distinctValues = dsValues
.AsEnumerable()
.Distinct(new DataRowComparer(dsValues.Columns))
.ToList();
您还可以为DataTable
创建扩展方法
static class DataTableExtension
{
public static IEnumerable<DataRow> DistinctRow(this DataTable table)
{
return table
.AsEnumerable()
.Distinct(new DataRowComparer(table.Columns));
}
}
用法
var distinctValues = dsValues
.DistinctRow()
.ToList();
关于c# - 从具有动态列的数据表中选择不同的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40307577/