【问题标题】:Is it possible to add GroupBy to a IQueryable<T> query?是否可以将 GroupBy 添加到 IQueryable<T> 查询?
【发布时间】:2020-12-10 21:20:18
【问题描述】:

我正在尝试对一些重复的东西进行通用化,但在这方面遇到了困难。我什至不知道这是否可能。我将我需要的内容放在代码块中,但如果需要,我很乐意澄清。任何帮助表示赞赏。

  public static async Task<object> LoadData<T>(IQueryable<T> query, string RequestGroup) where T : class
  {
     //this works
     //var Groupped = query.AsNoTracking().ToList().GroupBy(x => x.GetPropertyValue(RequestGroup)).Select(x => new { key = x.Key, count = x.Distinct().Count() });

     //How can I achieve this?
     var Groupped = query.GroupBy(x => x.GetPropertyValue(RequestGroup)).Select(x => new { key = x.Key, count = x.Distinct().Count() }).AsNoTracking().ToListAsync();

     return new { Data = Groupped };
  }

  public async Task<JsonResult> GetData()
  {
     var query = _context.Samples.AsQueryable();
     return Json(await LoadData(query, "Description"));
  }

  public class Sample
  {
     public int SampleID { get; set; }
     public string Description { get; set; }
  }

  #region Extensions
  public static object GetPropertyValue(this object obj, string name)
  {
     foreach (string part in name.Split('.'))
     {
        if (obj == null) { return null; }

        Type type = obj.GetType();
        PropertyInfo info = type.GetProperty(part);
        if (info == null) { return null; }

        obj = info.GetValue(obj, null);
     }
     return obj;
  }

  public static T GetPropertyValue<T>(this object obj, string name)
  {
     object retval = GetPropertyValue(obj, name);
     if (retval == null) { return default(T); }

     // throws InvalidCastException if types are incompatible
     return (T)retval;
  }
  #endregion

【问题讨论】:

  • RequestGroup 的可能值有多少?
  • 它是无限的。无论在 T 中传递的类的属性是什么。
  • coder_b,我在该链接中使用了其中一种解决方案,但它查询数据库中的所有行并稍后进行分组,这是我试图避免的。 var Groupped = query.GroupBy(GetColumnName&lt;T&gt;(RequestGroup.Selector).Compile()).Select(x =&gt; new { key = x.Key, count = x.Distinct().Count() }).ToList();

标签: c# asp.net-core ef-core-3.1


【解决方案1】:

感谢 coder_b,我使用了您提供的链接中的另一个回复,并得到了我想要的东西。如果其他人需要,这里是答案:

  public static async Task<object> LoadData<T>(IQueryable<T> query, string RequestGroup) where T : class
  {
     //this works
     //var Groupped = query.AsNoTracking().ToList().GroupBy(x => x.GetPropertyValue(RequestGroup)).Select(x => new { key = x.Key, count = x.Distinct().Count() });

     //How can I achieve this?
     //var Groupped = query.GroupBy(x => x.GetPropertyValue(RequestGroup)).Select(x => new { key = x.Key, count = x.Distinct().Count() }).AsNoTracking().ToListAsync();

     //Answer
     var Groupped = query.GroupBy(GetGroupKey<T>(RequestGroup)).Select(x => new { key = x.Key, count = x.Distinct().Count() }).ToList();

     return new { Data = Groupped };
  }

  public async Task<JsonResult> GetData()
  {
     var query = _context.Samples.AsQueryable();
     return Json(await LoadData(query, "Description"));
  }

  public class Sample
  {
     public int SampleID { get; set; }
     public string Description { get; set; }
  }

  #region Extensions
  private static Expression<Func<T, string>> GetGroupKey<T>(string property)
  {
     var parameter = Expression.Parameter(typeof(T));
     var body = Expression.Property(parameter, property);
     return Expression.Lambda<Func<T, string>>(body, parameter);
  }
  #endregion

【讨论】:

    猜你喜欢
    • 2019-11-14
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多