C# – DataTable: Get Max Value Using LINQ With Criteria Field (GroupBy)

c++datatablelinq

I have a DataTable structured like this:

username | price

"jack"        .01

"jack"        .02

"mary"       .03

"mary"       .04

How can I use LINQ on the DataTable to return the MAX PRICE FOR JACK (ex: .02)?

Code to setup the table (can ignore).

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);

This is where I get stuck. Want to return one row for Jack with his highest price (ex: ".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());

I'm not sure how to get Visual Studio to recognize the "Price" field as strongly typed. Guessing it's related to the issue.

Of course, two queries will work (one to filter by username, then another to select Max but it's not as elegant.

Related to this answer. Tried just about everything/looked all over but no luck.

Thanks.

Best Solution

You can't access "price" that way since there's no price member on DataRow. Access it just like you're doing with username (by column name):

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"])
    };

Of course you could simply do:

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