我在尝试从csharp中的DataSet中检索唯一值时遇到一些问题,这可能吗?
实际上我正在做这样的事情,从web服务中获取数据集:
webService.getInstructions(Username, Password, AppKey).Tables[0].Select(null, "account name asc");
因此,在这种情况下,我从帐户中获得了一个按字母顺序排列的列表,但此数据集中有一些重复的行。
有没有办法让这个数据集返回带有唯一“帐号”的值,并按“帐户名称”按字母顺序排序?
我认为代替 filterExpression 的东西会非常好。 :)
提前致谢
答案 0 :(得分:3)
就个人而言,我会更改网络服务,在服务器上进行此过滤和排序,以减少带宽需求,可能会返回一个简单的数据类型或自定义类(不是DataTable
或任何类似的)。但是LINQ会做这个工作......(重新阅读问题后更新)
var rows = dataset.Tables[0].AsEnumerable()
.DistinctBy(row => row.Field<string>("account number"))
.OrderBy(row => row.Field<string>("account name"))
.ToArray();
使用自定义DistinctBy
方法:
static IEnumerable<TSource> DistinctBy<TSource, TValue>(
this IEnumerable<TSource> source,
Func<TSource, TValue> selector)
{
HashSet<TValue> unique = new HashSet<TValue>();
foreach (var item in source)
{
if (unique.Add(selector(item))) yield return item;
}
}
答案 1 :(得分:0)
我会在数据表上使用一点linq魔法。
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("AccountNumber", typeof(System.Int32)));
dt.Columns.Add(new DataColumn("AccountName", typeof(System.String)));
for (int ii = 0; ii < 20; ii++)
dt.Rows.Add(new object[]{ii, "abc" + ii.ToString()});
dt.Rows[6][0] = 5;
dt.Rows[7][0] = 5;
dt.Rows[8][0] = 5;
//using grouping to isolate groups with just one item
var groupedRows = from row in dt.Select("", "AccountName ASC")
group row by row["AccountNumber"] into rowGroup
where rowGroup.Count() == 1
select rowGroup;
foreach (var group in groupedRows)
foreach(DataRow dr in group)
Console.WriteLine("Account #: {0} Account name: {1}", dr["AccountNumber"], dr["AccountName"]);
//using nested select to avoid grouping
Console.WriteLine();
Console.WriteLine("Nested select");
var z = from row in dt.Select()
where (from x in dt.Select() where (int) x["AccountNumber"] == (int) row["AccountNumber"] select x).Count() == 1
orderby row["AccountName"]
select row;
foreach(DataRow dr in z)
Console.WriteLine("Account #: {0} Account name: {1}", dr["AccountNumber"], dr["AccountName"]);
Console.WriteLine();
Console.WriteLine("Datatable select");
var y = from row in dt.Select()
where (from x in dt.Select("AccountNumber = " + row["AccountNumber"]) select x).Count() == 1
orderby row["AccountName"]
select row;
foreach (DataRow dr in y)
Console.WriteLine("Account #: {0} Account name: {1}", dr["AccountNumber"], dr["AccountName"]);
将结果打印到屏幕上,请注意缺少AccountNumber为“5”的任何行,因为它不是唯一的。另请注意,在第一个示例中,我使用了dataTable.Select()来进行排序,因为排序是相同的,而不管由于不唯一而删除了哪些行。第二个和第三个示例将为您提供一个可以直接绑定的IEnumerable行列表,第一个将为您提供一组包含各行的组。