简体   繁体   中英

LINQ query with distinct count

I am trying to construct a LINQ query in C# that will give me a list of distinct values from a column in a dataset with a count for each row. The results would look like this.

State   Count
AL       55
AK       40
AZ       2

Here is the SQL that does that.

SELECT name, COUNT(*) AS count
  FROM architecture arch
  GROUP BY name
  ORDER BY name

I've figured out the LINQ to get the DISTINCT values which is.

var query = ds.Tables[0].AsEnumerable()
    .OrderBy(dr1 => dr1.Field<string>("state"))
    .Select(dr1 => new {state = dr1.Field<string>("state")})
    .Distinct().ToList();

But I can't figure out how to get the COUNT(*) for each distinct value to work in LINQ. Any idea how I can add that into the LINQ query?

You need to group your results based on State and the Select count from the group like:

var query = ds.Tables[0].AsEnumerable()
            .GroupBy(r => r.Field<string>("state"))
            .Select(grp => new 
                            { 
                                state = grp.Key, 
                                Count = grp.Count()
                            })
            .OrderBy(o => o.state)
            .ToList();

Group all rows by value of state column. Then order groups by grouping key. And last step - project each group into anonymous object with grouping key (state) and count of rows in group:

var query = ds.Tables[0].AsEnumerable()
              .GroupBy(r => r.Field<string>("state"))
              .OrderBy(g => g.Key)
              .Select(g => new { State = g.Key, Count = g.Count() })
              .ToList();

Query syntax will look like (I'll skip converting to list, to avoid mixing syntaxes):

var query = from r in ds.Tables[0].AsEnumerable()
            group r by r.Field<string>("state") into g
            orderby g.Key
            select new {
                State = g.Key,
                Count = g.Count()
            };

Why bother with Distinct , when you can translate your SQL query to LINQ almost word-for-word? You can do it like this:

var query = ds.Tables[0].AsEnumerable()
    .GroupBy(dr1 => dr1.Field<string>("state"))
    .Select(g => new {
        State = g.Key
    ,   Count = g.Count()
    })
    .OrderBy(p => p.State)
    .ToList();

This produces a list of {State, Count} pairs. If you prefer a dictionary of state-to-count, you can change your query like this:

var query = ds.Tables[0].AsEnumerable()
    .GroupBy(dr1 => dr1.Field<string>("state"))
    .ToDictionary(g => g.Key, g => g.Count());

I think you need GroupBy

var query = ds.Tables[0].AsEnumerable()
              .GroupBy(dr1 => dr1.Field<string>("state"))
              .Select(g => new {state = g.Key, count = g.Count())
              .ToList();
var query = ds.Tables[0].AsEnumerable()
              .GroupBy(x=>x.Field<string>("state"))
              .Select( g => new{
                   state = g.Key,
                   count = g.Count()
              });

Guess what, the equivalent of group by is group by :)

        var query = from dr1 in ds.Tables[0].AsEnumerable()
                    group dr1 by dr1.Field<string>("state") into state
                    select new { State = state.Key, Count = state.Count() };
var stat = from row in ds.Tables[0].AsEnumerable()
group row by new
{
  Col1 = row["Name"],
} into TotalCount
select new
{
  ActionName = TotalCount.Key.Col1,
  ActionCount = TotalCount.Count(),
 };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM