DataTable:使用LINQ With Criteria字段获取最大值(GroupBy)

时间:2012-03-03 23:37:27

标签: c# linq datatable

我有一个像这样结构化的DataTable:

  

用户名|价格

     

“插口” 0.01

     

“插口” 0.02

     

“MARY” 0.03

     

“MARY” 0.04

如何在DataTable上使用LINQ返回MAX PRICE FOR JACK(例如:.02)?

设置表的代码(可以忽略)。

DataTable tbl = new DataTable();
tbl.Columns.Add("username");
tbl.Columns["username"].DataType = typeof(string);

tbl.Columns.Add("price");
tbl.Columns["price"].DataType = typeof(double);

DataRow r = tbl.NewRow();
r["username"] = "jack"; r["price"] = .01;
tbl.Rows.Add(r);

r = tbl.NewRow();
r["username"] = "jack"; r["price"] = .02;
tbl.Rows.Add(r);

r = tbl.NewRow();
r["username"] = "mary"; r["price"] = .03;
tbl.Rows.Add(r);

r = tbl.NewRow();
r["username"] = "mary"; r["price"] = .04;
tbl.Rows.Add(r);

这是我被卡住的地方。想以最高价格为杰克退回一行(例如:“。02”)。

var result =
    from row in tbl.AsEnumerable() 
    where (string) row["username"] == "jack"
    group row by new {usernameKey = row["username"]} into g  
    select new
    {
        //WHAT IS THE LINQ SYNTAX TO USE HERE?    
        jackHighestPrice = g.Max(x => x.price); //This doesn't work, VS doesn't see the "price" field as strongly typed (not sure why).
    };

//This should display Jack's highest price.  
MessageBox.Show(result.First().jackHighestPrice.ToString());

我不确定如何让Visual Studio将“Price”字段识别为强类型。猜猜它与这个问题有关。

当然,有两个查询可以使用(一个用于按用户名过滤,另一个用于选择Max,但它不是那么优雅。

this answer相关。几乎尝试了一切/看了一遍但没有运气。

感谢。

3 个答案:

答案 0 :(得分:10)

由于price上没有DataRow成员,您无法以此方式访问“价格”。像访问username一样访问它(按列名称):

var result =
    from row in tbl.AsEnumerable() 
    where (string) row["username"] == "jack"
    group row by new {usernameKey = row["username"]} into g  
    select new
    { 
        jackHighestPrice = g.Max(x => x["price"])
    };

当然你可以这样做:

string max = tbl.AsEnumerable()
        .Where(row => row["username"].ToString() == "jack")
        .Max(row => row["price"])
        .ToString();

答案 1 :(得分:5)

你有没有尝试过:

var query = tbl.AsEnumerable().Where(tr => (string) tr["username"] == "jack")
               .Max(tr => (double) tr["price"]);

答案 2 :(得分:3)

var result =
    from row in tbl.AsEnumerable()
    where (string)row["username"] == "jack"
    let x = new { usernameKey = (string)row["username"], (double)price = row["price"] }
    group x by x.usernameKey into g
    select g.Max(x => x.price);

但是,由于您只允许一个用户,因此不需要分组。只需选择@WorldIsRound建议的最大值。