Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

linq

datatable

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.

like image 799
rr789 Avatar asked Mar 03 '12 23:03

rr789


2 Answers

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();
like image 55
Andrew Whitaker Avatar answered Nov 15 '22 00:11

Andrew Whitaker


Did you try:

var query = tbl.AsEnumerable().Where(tr => (string) tr["username"] == "jack")
               .Max(tr => (double) tr["price"]);
like image 33
WorldIsRound Avatar answered Nov 15 '22 01:11

WorldIsRound