0
  public ActionResult Query(List<string> sortable_bot, List<string> sortable_top)
    {
        string gro = "from st in context.Customers";

        for (int i = 0; i < sortable_top.Count; i++)
        {
            gro += " group st by st." + sortable_top[i].ToString();
        }

        string into = " into g select new Group2() { Key = g.Key, Count = g.Count() }";
        gro += into;

        using (var context = new NwContext())
        {
            *var que = gro;
            return View(que.ToList());
        }
    }

I put a breakpoint at the star and gro string equals from st in context.Customers group st by st.Country into g select new Group2() { Key = g.Key, Count = g.Count() }

but this is not working. If I write directly like this var que= from st in context.Customers group st by st.Country into g select new Group2() { Key = g.Key, Count = g.Count() }; that worked.

8
  • Doing linq in strings doesn't seem to be correct... and what should *var be? Even with dynamic linq you have separate methods .Where(string), .Select(string) ... Commented Jun 28, 2018 at 8:43
  • @xanatos to understand where I put a breakpoint Commented Jun 28, 2018 at 8:44
  • 2
    You can't just put C# code in a string and then call it as if it were code. Especially not Linq, which gets translated to C# statements first and then compiled to runnable code. The approach you took to solve the actual problem you're trying to solve is not going to solve the problem, so you have an XY problem. Explain your actual problem and find a different approach. Commented Jun 28, 2018 at 8:44
  • @CodeCaster do you know another solution? Commented Jun 28, 2018 at 8:45
  • Not if you don't explain the actual problem you're trying to solve. Commented Jun 28, 2018 at 8:46

2 Answers 2

2

Extended example using System.Linq.Dynamic.Core (that has a nuget):

Given:

public class KeyCount
{
    public dynamic Key { get; set; }
    public int Count { get; set; }
}

Then you can:

public KeyCount[] Query(List<string> sortable_top)
{
    string gro = string.Join(",", sortable_top);

    using (var context = new MyDbContext())
    {
        IQueryable result = context.Customers;
        result = result.GroupBy("new (" + gro + ")", "it");
        IEnumerable<KeyCount> result2 = result.Select<KeyCount>("new (it.Key, it.Count() as Count)") ;
        return result2.ToArray();
    }
}

Note how I Selected to a semi-static-type object (KeyCount), where Key is still dynamic (because in the end the number of columns used for the grouping is dynamically selected at runtime), while Count is a int.

With only two fields it is even possible to use Tuple<dynamic, int>:

public Tuple<dynamic, int>[] Query(List<string> sortable_bot, List<string> sortable_top)
{
    string gro = string.Join(",", sortable_top);

    using (var context = new MyDbContext())
    {
        IQueryable result = context.Products;
        result = result.GroupBy("new (" + gro + ")", "it");
        var result2 = result.Select<Tuple<dynamic, int>>("new (it.Key, it.Count() as Count)");
        return result2.ToArray();
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

System.Dynamic.Linq can't parse the whole linq-query. It can parse strings to create lambda expressions.

For example this query is similar to your query:

var que= from st in context.Customers 
group st by st.Country into g 
select new { Key = g.Key, Count = g.Count() };

can be rewritten with System.Dynamic.Linq:

var que = context.Customers.
  .GroupBy("Country", "it")
  .Select("new (it.Key as Key, it.Count() as Count)");

then you can read result like this:

foreach (dynamic group in que)
{
    Console.WriteLine(group.Key + " " + group.Count);
    // Populate collection of Group2
}

To group by multiple columns you need to construct two strings (one for GroupBy and one for Select) and use it like this:

var que = context.Customers.
  .GroupBy("new ( it.Country, it.City)", "it")
  .Select("new (it.Country, it.City, it.Count() as Count)");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.