C#DataSet - 基于列检索唯一值

时间:2009-11-06 10:04:13

标签: c# .net asp.net-mvc dataset return-value

我在尝试从csharp中的DataSet中检索唯一值时遇到一些问题,这可能吗?

实际上我正在做这样的事情,从web服务中获取数据集:

 webService.getInstructions(Username, Password, AppKey).Tables[0].Select(null, "account name asc");

因此,在这种情况下,我从帐户中获得了一个按字母顺序排列的列表,但此数据集中有一些重复的行。

有没有办法让这个数据集返回带有唯一“帐号”的值,并按“帐户名称”按字母顺序排序?

我认为代替 filterExpression 的东西会非常好。 :)

提前致谢

2 个答案:

答案 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行列表,第一个将为您提供一组包含各行的组。