LINQ从字符串查询

时间:2016-03-01 00:34:32

标签: string linq build field

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

在我的程序的第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) ; ";
            }

那么,有什么想法吗?这不是一个数据库,我发现的例子并没有在datatable上工作。如果我可以将这个字符串传递给Where子句,我的工作就完成了。我无法弄清楚如何以任何其他方式构建此查询而不是手动,这会打击chunkskis。或者,如果有一种方法可以告诉Linq在没有明确调用它们的情况下搜索每一列?

3 个答案:

答案 0 :(得分:0)

我认为实现此目的的唯一方法是使用Microsoft.CSharp and System.CodeDom.Compiler namespaces,因为这样可以将字符串编译成要运行的程序集。

'http://php.net/manual/en/function.empty.php'

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

编辑:通过这个,我的意思是处理你创建的字符串。

答案 1 :(得分:0)

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

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#]

答案 2 :(得分:0)

如果您确实想检查数据行的任何字段值是否包含过滤器文本,您可以循环遍历行,每行遍历其值并检查行中是否有任何值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)))