Anthony VINEE
Anthony VINEE

Reputation: 67

Group by with Linq Dynamic

I would like to make a group to a value chosen from a dropdown list, but the value can be a DateTime or a String, and I want to provide only one case. Do you have any idea to do this ?

My code :

public class Personne
{
    public String _NOM { get; set; }
    public DateTime _DDN { get; set; }
    public String _VILLE { get; set; }

    public Personne(String nom, DateTime ddn, String ville)
    {
        this._NOM = nom;
        this._DDN = ddn;
        this._VILLE = ville;
    }
}

And here is the buttonClick event :

List<Personne> _liste = new List<Personne>();
_liste.Add(new Personne("toto", new DateTime(1993, 3, 23), "Paris"));
_liste.Add(new Personne("tata", new DateTime(1993, 3, 23), "New-York"));
_liste.Add(new Personne("titi", new DateTime(1987, 2, 10), "Paris"));

var qry = _liste.AsQueryable().OrderBy(listeCritere.SelectedValue)
    .GroupBy(listeCritere.SelectedValue, "It", null);

if (listeCritere.SelectedValue == "_DDN")
{
    foreach (IGrouping<DateTime, Personne> item in qry)
    {
        Response.Write(item.Key + "<br/>");

        foreach (Personne p in item)
        {
            Response.Write("&nbsp;&nbsp;&nbsp;&nbsp; Nom complet : " + p._NOM + "<br/>");
        }
    }
}
else
{
    foreach (IGrouping<String, Personne> item in qry)
    {
        Response.Write(item.Key + "<br/>");

        foreach (Personne p in item)
        {
            Response.Write("&nbsp;&nbsp;&nbsp;&nbsp; Nom complet : " + p._NOM + "<br/>");
        }
    }
}

Upvotes: 2

Views: 189

Answers (2)

Hogan
Hogan

Reputation: 70513

In linq you can make functions in the closure -- here we just make a function to return the key value (but always as string):

string gby = "NOM";
//string gby = "DDN";
//string gby = "VILLE";

var qry = _liste
             .GroupBy(x => {
                string result = "";
                switch (gby) 

                {
                  case "NOM": result = x._NOM; break;
                  case "DDN" : result = x._DDN.ToString(); break;
                  case "VILLE" : result = x._VILLE ; break;
                }
                return result;
            }
            ).ToList();

Upvotes: 1

poke
poke

Reputation: 387537

You could just loop over IEnumerable<Personne> instead, and then get the correct type for the key inside the loop:

var qry = _liste.AsQueryable().OrderBy(listeCritere.SelectedValue)
    .GroupBy(listeCritere.SelectedValue, "It", null);

foreach (IEnumerable<Personne> item in qry)
{
    if (item is IGrouping<DateTime, Personne>)
        Response.Write(((IGrouping<DateTime, Personne>)item).Key + "<br/>");
    else if (item is IGrouping<object, Personne>)
        Response.Write(((IGrouping<object, Personne>)item).Key + "<br/>");

    foreach (Personne p in item)
    {
        Response.Write("&nbsp;&nbsp;&nbsp;&nbsp; Nom complet : " + p._NOM + "<br/>");
    }
}

You could also move the loop to a generic function:

public void ButtonClickHandler(object sender, EventArgs e)
{
    var qry = _liste.AsQueryable().OrderBy(listeCritere.SelectedValue)
        .GroupBy(listeCritere.SelectedValue, "It", null);

    if (listeCritere.SelectedValue == "_DDN")
        WritePersonneResponse<DateTime>(Response, qry);
    else
        WritePersonneResponse<string>(Response, qry);
}

public void WritePersonneResponse<T>(HttpResponse response, IQueryable qry)
{
    foreach (IGrouping<T, Personne> item in qry)
    {
        response.Write(item.Key + "<br/>");

        foreach (Personne p in item)
        {
            response.Write("&nbsp;&nbsp;&nbsp;&nbsp; Nom complet : " + p._NOM + "<br/>");
        }
    }
}

Upvotes: 1

Related Questions