好的,我发现很多网站都提到了这个问题,但没有一个与我需要做的完全匹配。我有一个程序,根据我从亚马逊网络服务收集的数据生成大量数据表。我正在尝试编写一个函数,允许我在提供的数据表的任何列中搜索特定的字符串。
在我的程序的第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在没有明确调用它们的情况下搜索每一列?
答案 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);
见
答案 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)))