【问题标题】:C# Linq - Create a dynamic select query based on user inputC# Linq - 根据用户输入创建动态选择查询
【发布时间】:2021-02-07 21:42:05
【问题描述】:

用例:用户需要能够选择要查看的输入字段。然后,该字段请求通过查询传递,该查询随后返回用户输入的列表以供查看。基本上,SQL 中的动态 Select 语句,其中 FROM 列是用户定义的变量。

方法: 使用 C# 和 Linq 我编写了以下 Linq 查询来返回数据,但是,我无法将查询中的实际字段名称与具有由用户设置。

研究:我已经查看了十几个类似的问题和文章,它们似乎都比我想要完成的要复杂得多,而且它们似乎没有回答我的问题有充分的;或者我只是不明白解决方案实际上是什么。我尝试过使用 Dynamic Linq,但运气不佳,使用 Expression Trees 似乎比我希望的实际需要复杂得多。

明确定义的字段选择:

                    var Values = conn.Table<DataTable>()
                                      .Where(t => t.User_ID == ID)
                                      .Select(t => FieldName).Distinct().ToList();

变量字段选择

                   //allowing the user to set the value
                   string UserSelectedField = y_List[0].ToString(); 
                   var Values = conn.Table<DataTable>()
                                    .Where(t => t.User_ID == ID)
                                    .Select(t => @UserSelectedField).Distinct().ToList();

在第一个查询中,我得到了我正在寻找的结果,但它只能从代码中键入的字段返回值。

第二个返回对象名称,如 {FieldName = FieldName}。

我也尝试在查询中将其连接起来,但没有奏效。认为它不会,但值得一试。

【问题讨论】:

  • 如果您需要快速简单的 - 您可以使用这样的库:dynamic-linq.net
  • 您应该能够使用LINQKit 并创建字符串查询,但是有一些很大的限制 - 例如。你不会在编译时知道Values 的静态类型,所以你不能直接引用任何字段。
  • @Evk 他们所有的自述文件数据都进入了一个不存在的页面,并且他们的示例由于某种原因对我不起作用。我以前试过。我确定我做错了什么或某事,但它不起作用,并且没有任何我能找到有用的说明。

标签: c# sql linq dynamic


【解决方案1】:

你必须编写自己的扩展,这里限制你必须知道字段的类型:

public static class MyExtensions
{
    public class DynamicHelper<T>
    {
        private IQueryable<T> _query;

        internal DynamicHelper(IQueryable<T> query)
        {
            _query = query;
        }

        public IQueryable<TResult> SelectByFieldName<TResult>(string fieldName)
        {
            return MyExtensions.SelectByFieldName<T, TResult>(_query, fieldName);
        }
    }

    public static DynamicHelper<T> Dynamic<T>(this IQueryable<T> query)
    {
        return new DynamicHelper<T>(query);
    }

    private static IQueryable<TResult> SelectByFieldName<T, TResult>(IQueryable<T> query, string fieldName)
    {
        var param = Expression.Parameter(typeof(T), "e");
        Expression body = Expression.PropertyOrField(param, fieldName);
        if (body.Type != typeof(TResult))
            body = Expression.Convert(body, typeof(TResult));
        var lambda = Expression.Lambda<Func<T, TResult>>(body, param);
        return query.Select(lambda);
    }
}

及用法

string UserSelectedField = y_List[0].ToString(); 
var Values = conn.Table<DataTable>()
   .Where(t => t.User_ID == ID)
   .Dynamic().SelectByFieldName<string>(UserSelectedField)
   .Distinct()
   .ToList();

【讨论】:

  • 感谢@Svyatoslav Danyliv。但是,当我尝试您的代码时,我在 'DynamicHelper' (CS0246 命名空间错误)的第二个实例的 '' 上遇到错误。 在“return new DynamicHelper' 我得到 CS0122 (protection level error) 并且在 'Expression.Convert(body, typeof(TResult))' 我得到一个 CS0029 错误关于一元到 MemberExpression 隐式转换。我>
  • 抱歉,更新了答案。只是在浏览器中编写,无需编译。
  • .Dynamic() 是内置在命名空间中的属性或方法,还是对 DynamicHelper Dynamic 方法的调用?出于某种原因,我收到一个编译器错误,指出我的表不包含 Dynamic() 的定义或无法找到将 TableQuery 作为第一个参数的可访问扩展。这个扩展是否需要与 Table 一起进入课堂?还是应该进入自己的类?
  • TableQuery??它是什么?它是 IQueryable 吗?
  • DataTable 是被查询的表,错误发生在上面.Dynamic() 的“和用法”部分。我假设 TableQuery 指的是“MyExtensions”类中的扩展方法“Dynamic”,因为它需要一个参数“this IQueryable query”我假设这是被引用的查询到。
猜你喜欢
  • 2020-01-24
  • 1970-01-01
  • 1970-01-01
  • 2020-02-15
  • 1970-01-01
  • 2015-02-11
  • 2015-10-01
  • 2011-02-18
  • 1970-01-01
相关资源
最近更新 更多