【问题标题】:LINQ Query from string来自字符串的 LINQ 查询
【发布时间】:2016-03-01 00:34:31
【问题描述】:

好的,我发现很多网站都提到了这个问题,但没有一个完全符合我的需要。我有一个程序可以根据我从亚马逊网络服务收集的数据生成大量数据表。我正在尝试编写一个函数,允许我在提供的数据表的任何列中搜索特定字符串。

在我的程序版本 1 中,我根据预定义的表结构手动构建了查询:

 newbie = RawEC2Results.AsEnumerable().Where(p => p.Field<string>("AccountID").Contains(FilterTagText.Text) || 
p.Field<string>("Profile").Contains(FilterTagText.Text) ||
p.Field<string>("Region").Contains(FilterTagText.Text) ||
p.Field<string>("Name").Contains(FilterTagText.Text) ||
p.Field<string>("InstanceID").Contains(FilterTagText.Text) ||
p.Field<string>("AvailabilityZone").Contains(FilterTagText.Text) ||
p.Field<string>("Platform").Contains(FilterTagText.Text) ||
p.Field<string>("Status").Contains(FilterTagText.Text) ||
p.Field<string>("Events").Contains(FilterTagText.Text) ||
p.Field<string>("EventList").Contains(FilterTagText.Text) ||
p.Field<string>("Tags").Contains(FilterTagText.Text) ||
p.Field<string>("Priv_IP").Contains(FilterTagText.Text) ||
p.Field<string>("Pub_IP").Contains(FilterTagText.Text) ||
p.Field<string>("Pub_DNS").Contains(FilterTagText.Text) ||
p.Field<string>("State").Contains(FilterTagText.Text) ||
p.Field<string>("vType").Contains(FilterTagText.Text) ||
p.Field<string>("iType").Contains(FilterTagText.Text) ||
p.Field<string>("SecurityGroups").Contains(FilterTagText.Text));

维护起来很繁琐,因为每次更改列以添加新数据时我都必须更新。我可以生成一个字符串以根据任何给定的表生成查询,但不知道如何处理它。

            string nocasequery = "p=> ";
        int colno = Table2Filter.Columns.Count;

        for (int i =0; i < Table2Filter.Columns.Count  ;i++)
        {
            if (i == colno)
            {
                CASEquery +=   @"p.Field<string>(""+Table2Filter.Columns[i]+  "").Contains(FilterTagText.Text) ; ";
                nocasequery += @"p.Field<string>(""+Table2Filter.Columns[i]+  "").ToLower().Contains(FilterTagText.Text) ; ";
            }

那么,有什么想法吗?这不是数据库,我找到的示例不适用于数据表。如果我可以将此字符串传递给 Where 子句,我的工作就完成了。除了手动之外,我无法弄清楚如何以任何其他方式构建此查询,这让 chunkskis 感到震惊。或者是否有一种方法可以告诉 Linq 搜索每一列而无需我明确调用它们?

【问题讨论】:

    标签: string linq build field


    【解决方案1】:

    我相信实现这一点的唯一方法是使用Microsoft.CSharp and System.CodeDom.Compiler namespaces,因为这将允许您将字符串编译成要运行的程序集。

    'http://www.codeproject.com/Tips/715891/Compiling-Csharp-Code-at-Runtime'

    该链接应该为您提供一些有关如何完成此操作的指导!

    编辑:我的意思是处理您创建的字符串。

    【讨论】:

      【解决方案2】:

      您可以轻松地自己动态创建这样的查询。只需使用 DataTable.Select 具有类似 sql 语法的方法:

      void Main()
      {
          var dt = new DataTable();
          dt.Columns.Add("foo", typeof(string));
          dt.Columns.Add("bar", typeof(string));
      
          dt.Rows.Add("baz", "baaz");
          dt.Rows.Add("qux", "quux");
      
          var results = dt.Select("foo like '%a%'"); // finds baz
      }
      

      您可以列出所有列并从中构建查询字符串,在本示例中将是:

      foo like '%{0}%' OR bar like '%{0}%'
      
      var columnNames =
          dt.Columns.Cast<DataColumn>()
          .Select(c => c.ColumnName);
      
      var query = string.Join(" OR ", columnNames.Select(x => x + " like '%{0}%'"));
      
      query = string.Format(query, "a");
      var results = dt.Select(query);
      

      DataTable.Select Method (String)

      DataView RowFilter Syntax [C#]

      【讨论】:

        【解决方案3】:

        如果您真的想检查数据行的 any 字段值是否包含过滤器文本,您可以遍历行,并逐行遍历其值并检查一行中是否有任何值Contains()过滤文字:

        var text = FilterTagText.Text;
        var matches = dt.AsEnumerable() // dt is a DataTable
                        .Where(r => dt.Columns.OfType<DataColumn>()
                                      .Select(dc => (r[dc.Caption] ?? string.Empty).ToString())
                                      .Any(s => s.Contains(text)))
        

        【讨论】:

          猜你喜欢
          • 2011-09-23
          • 1970-01-01
          • 1970-01-01
          • 2015-10-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多