【问题标题】:Dynamic linq query string not working动态 linq 查询字符串不起作用
【发布时间】:2018-06-28 08:40:06
【问题描述】:
  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());
        }
    }

我在星号处放了一个断点,gro 字符串等于from st in context.Customers group st by st.Country into g select new Group2() { Key = g.Key, Count = g.Count() }

但这不起作用。如果我像这样直接写var que= from st in context.Customers group st by st.Country into g select new Group2() { Key = g.Key, Count = g.Count() };,那就行了。

【问题讨论】:

  • 在字符串中执行 linq 似乎不正确...*var 应该是什么?即使使用动态 linq,您也有单独的方法 .Where(string), .Select(string) ...
  • @xanatos 了解我放置断点的位置
  • 你不能把 C# 代码放在一个字符串中,然后像代码一样调用它。尤其是 Linq,它首先被翻译成 C# 语句,然后然后被编译成可运行的代码。你为解决你试图解决的实际问题而采取的方法并不能解决问题,所以你有一个 XY 问题。解释您的实际问题并找到不同的方法。
  • @CodeCaster 你知道另一种解决方案吗?
  • 如果您不解释您要解决的实际问题,则不会。

标签: .net asp.net-mvc linq


【解决方案1】:

使用System.Linq.Dynamic.Core 的扩展示例(具有nuget):

给定:

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

那么你可以:

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();
    }
}

注意我是如何将Selected 到一个半静态类型的对象(KeyCount),其中Key 仍然是dynamic(因为最后用于分组的列数是动态选择的运行时),而Countint

只有两个字段,甚至可以使用Tuple&lt;dynamic, int&gt;

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();
    }
}

【讨论】:

    【解决方案2】:

    System.Dynamic.Linq 无法解析整个 linq 查询。它可以解析字符串以创建 lambda 表达式。

    例如,此查询与您的查询类似:

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

    可以用System.Dynamic.Linq重写:

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

    那么你可以像这样读取结果:

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

    要按多列分组,您需要构造两个字符串(一个用于GroupBy,一个用于Select)并像这样使用它:

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

    【讨论】:

      猜你喜欢
      • 2021-02-06
      • 2011-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多