【问题标题】:Ordering by ICollection property using its name as string with Dynamic Linq Library使用动态 Linq 库的名称作为字符串按 ICollection 属性排序
【发布时间】:2017-07-24 03:26:17
【问题描述】:

我已经搜索了几乎所有我能找到的问题、博客或文档来帮助我找到这个问题的答案。有一些实际上帮助我更接近它,​​但我还没有解决它,因为大多数要么已经过时,要么与我需要的东西不符。不要费心告诉我关于表达式的事情,因为如果我要走更长的路,我就不会使用这个库。

我的项目目标是通过使用通用方法、仅使用表/列名称字符串和用于过滤的值来提供过滤和排序。长话短说,我有两张表,关系为 1 到 n,基本上是这样连接的,我想按客户的名字订购:

public partial class Transactions{
    public ICollection<Customer> customer { get; set; };
}

public partial class Customer{
    public string name { get; set; };
}

到目前为止,我几乎需要实现我想要的,除了弄清楚如何正确构造 OrderBy 字符串,在某种程度上我会使用单个 ICollection 结果。

到目前为止,我所拥有的几乎是这样的(抱歉我的文档过于冗长):

using System.Linq.Dynamic;
using System.Reflection;

namespace com.betha.common
{
    public class Filter
    {
        /// <summary>
        /// Dictionary of codenames and column names populated by a different, specific class (properties.Add("customer", "tb_customer.name"))
        /// </summary>
        public Dictionary<string, string> properties;

        public Filter(Dictionary<string, string> properties)
        {
            this.properties = properties;
        }

        /// <summary>
        /// Generic method designed to filter and order using just lists of column names and values
        /// </summary>
        /// <typeparam name="T">Type of the first IQueryable</typeparam>
        /// <typeparam name="T2">Type of the second IQueryable</typeparam>
        /// <param name="query">IQueryable containing the results from the parent table (context.table1).AsQueryable();</param>
        /// <param name="query2">IQueryable containing a single result from a descendant table (context.table2.Select(t2 => t2.field).FirstOrDefault()).AsQueryable();</param>
        /// <param name="prop">Property codename that if used, matches a properties codename Key</param>
        /// <param name="descend">Condition for ascending or descending results</param>
        /// <returns>Ordered and/or filtered IQueryable</returns>
        public IQueryable<T> FilterandOrder<T, T2>(IQueryable<T> query, IQueryable<T2> query2, string prop = null, string descend = null)
        {
            if (!String.IsNullOrEmpty(prop))
            {
                foreach (KeyValuePair<string, string> item in properties)
                {
                    if (prop == item.Key)
                    {
                        prop = item.Value;
                    }
                }
                T2 subprop = query2.FirstOrDefault();

                if (prop.Contains("."))
                {
                    switch (prop.Split('.'))
                    {
                        default:
                            PropertyInfo property = subprop.GetType().GetProperty(prop.Split('.')[1]);
                            ParameterInfo[] index = property.GetIndexParameters();
                            object value = subprop.GetType().GetProperty(prop.Split('.')[1]).GetValue(subprop, index);

                            //This is the main issue, I have pretty much everything I should need, but I can't imagine how to write this OrderBy string properly.
                            //If I were to do it without the library: table.OrderBy(t => t.table2.Select(t2 => t2.field).FirstOrDefault());
                            //Without ordering by an ICollection property, like in the else below, string should look like: "field".
                            //Or in case of a 1 to 1 relationship, "table2.field".
                            query = DynamicQueryable.OrderBy(query, prop + (descend == "dec" ? " descending" : ""), value);
                            break;
                    }
                }
                else
                {
                    query = DynamicQueryable.OrderBy(query, prop + (descend == "dec" ? " descending" : ""));
                }
            }

            return query;
        }
    }
}

【问题讨论】:

标签: c# linq asp.net-mvc-5 dynamic-linq


【解决方案1】:

您可以将t =&gt; t.table2.Select(t2 =&gt; t2.field).FirstOrDefault() 替换为支持的函数Min()

OrderBy("table2.Min(field)");

【讨论】:

  • 成功了。我还是不敢相信。一直停留在这个问题上,现在已经 3 周了。谢谢。
  • 另外,多亏了这一点,我什至不再需要这个方法的重载版本,它有 2 个泛型类型。再次感谢。
  • 很高兴它成功了。太糟糕了DynamicQuery 不是一个活跃的项目。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多