我需要针对DataTable运行LINQ查询,以使用多个列获取不同的值。如果我知道我需要事先选择的列,我可以在Select distinct rows from datatable in Linq使用David Hoarser的答案:
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();
但由于我不知道有多少列需要选择Distinct,因为cols列表可能会有所不同,所以这不会起作用。如何循环列列表以构建我的Select语句以最终获得我的Distinct值?
答案 0 :(得分:4)
您可以为该任务实施自定义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();
答案 1 :(得分:0)
<svg width="640" height="480" viewbox="0 0 640 480" style="border: 1px dotted black;">
<g transform="translate(270, 190)">
<line x1="0" y1="0" x2="100" y2="0" stroke="black"></line>
<line x1="100" y1="0" x2="100" y2="100" stroke="black"></line>
<line x1="100" y1="100" x2="0" y2="100" stroke="black"></line>
<line x1="0" y1="100" x2="0" y2="0" stroke="black"></line>
</g>
</svg>