tags:

views:

1031

answers:

3

Hello,

I have an object that contains these three properties: ID, DATE and NAME and want to query it with linq yielding the same results as if written in the sql statement below.

SELECT ID, MAX(DATE), NAME 
FROM TABLE
GROUP BY ID

Here is what I have so far with linq:

var grouped = from a in table
group a by a.ID into g
select new fooObject()
{
DATE= g.Max(a => a.DATE),
NAME= g.Select(a => a.Name).ToString(),
ID= g.Select(a => a.ID)
};

Thanks in advance for any help.

A: 

var grouped = (from a in table where a.Date == (from d in table where a.ID == d.ID select Date).Max() select a).OrderBy(i => i.ID);

KP
+3  A: 

Given your updated explanation, here is my proposed solution. I've also cleaned up the code a bit.

var grouped = from item in table
              group item by item.Id into g
              let itemMaxDate = g.MaxBy(i => i.Date)
              select new FooObject()
              {
                  Id = g.Key,
                  Name = itemMaxDate.Name,
                  Date = itemMaxDate.Date
              };

You then need to define the MaxBy extension method. (Unfortunately LINQ does include one built-in.)

public static TSource MaxBy<TSource, TResult>(this IEnumerable<TSource> 
    collection, Func<TSource, TResult> func)
{
    var comparer = Comparer<TResult>.Default;
    TSource maxItem = null;
    foreach (var item in collection)
    {
        if (comparer.Compare(item, maxItem) > 0)
            maxItem = item;
    }
    return maxItem;
}

I believe this ought to be what you want now. Let me know if it does the job for you.

Noldorin
"group item by item.ID into group"needs to be"group item by item.ID into g"
Matthew Steeples
I don't want to group on NAME. The data would look like the following. I want to group the ID's and take the row with the max date and whatever name is associated.ID DATE NAME1 1/1/09 SMH1 1/2/09 ASD2 1/3/09 FGH2 1/4/09 JKLThe result would beID DATE NAME1 1/2/09 ASD2 1/4/09 JKL
SMH
Well, that did not work for describing the data.
SMH
Ok, I've updated my answer now. Should do exactly what you want. It should also be just about as efficient as possible for LINQ, since it uses the custom MaxBy method.
Noldorin
A: 
SELECT ID, MAX(DATE), NAME
FROM TABLE
GROUP BY ID

Column 'TABLE.NAME' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

David B
Looks like I need a different approach, maybe a sub query? I only want records grouped by ID and MAX(DATE).
SMH
You might try : MAX(Name)
David B