tags:

views:

112

answers:

3

How do I create a method to return the results of a group by in LINQ to sql such as the one below:

internal SomeTypeIDontKnow GetDivisionsList(string year)
{
    var divisions =  from p in db.cm_SDPs
                          where p.acad_period == year
                          group p by new
                          {
                              p.Division
                          } into g
                          select new
                          {
                              g.Key.Division
                          };
    return divisions;
}

I can't seem to define a correct return type. I think it is because it's an anonymous type but haven't got my head around it yet. Do I need to convert it to a list or something?

The results would just be used for filling a combo box.

A: 

LINQ is "lazy". You need to do a ToList() ( or any of the other appropriet methods ) and get an IEnumerable<T>. Read this about Lazy Loading.

Filip Ekberg
+4  A: 

You can't* return an anonymous type.

Either you'll need to work out what type your query returns, and return specifically that, or you can rename the method BindDivisionsList(...) and perform your databinding inside the method.

I'd recommend the former (Making some assumptions about your types here):-

internal IEnumerable<Division> GetDivisionsList(string year)
{
    IEnumerable<Division> divisions =
        from p in db.cm_SDPs
        where p.acad_period == year
        group p by new
        {
            p.Division
        } into g
        select g.Key.Division;

    return divisions;
}

or alternately (and I'd generally do it this way):-

internal IEnumerable<Division> GetDivisionsList(string year)
{
    IEnumerable<Division> divisions =
        db.cm_SPDs.Where(x => x.acad_period == year)
                  .Select(x => x.Division)
                  .Distinct();

    return divisions;
}

Edit: *You can, just not usefully - you'd have to return "object". See:-

http://msdn.microsoft.com/en-us/library/bb397696.aspx

-but unless you've got a good reason, you probably want to be working with named types whenever you can.

Iain Galloway
Thanks for the help sorted now. I knew I could bind in the method but wanted to maintain the class separate to the UI as much as possible.
PeteT
A: 

You aren't really returning a 'group by' result - you're just returning a regular LINQ collection (in this case, IEnumerable<Division>). As Iain points out, you can achieve the same result using the .Distinct operator rather than grouping and then selecting from those groups.

If you do want to return actual group results, you could possibly convert the result set to a Dictionary<Key, List<Element>> - it won't be able to natively return as that type, but the IGrouping interface seems to be possibly isomorphic to this structure.

In order words, when I need to picture an IGrouping structure, I picture a dictionary where each key/value pair is a group, with

  • each key representing the distinct values in the Group By clause
  • each value representing the Elements from the original collection that match the Group By clause, i.e. the members of the Group.
Kirk Broadhurst