C# 使用带有 where 子句的 Linq 查询作为 dataTable 上的变量

Posted

技术标签:

【中文标题】C# 使用带有 where 子句的 Linq 查询作为 dataTable 上的变量【英文标题】:C# Using Linq Query with where clause as variable on dataTable 【发布时间】:2017-01-12 16:48:57 【问题描述】:

我看到了不同的示例和问题,但我不知道如何成功编写此查询。 where 子句条件在 filter.condition

  private object[] GetValueFromLookup(MultipleKeyConditionBuilder filter, string lookupValueField, DataTable datatableLookup)
    

        Func<int, string> whereClause = test => filter.Condition;

        IEnumerable<object> query =
        from rows in datatableLookup.AsEnumerable().Where(whereClause)
        select rows.Field<object>(lookupValueField);
        return query.ToArray();

    

我收到此错误。我尝试了不同的方法,但不幸的是我无法理解如何解决它。

无法从 'System.func (int,string)' 转换为 'System.func(system.Data.DataRow,int,bool)'

MultipleKeyConditionBuilder。这个函数给出过滤条件。它被定义为。

public MultipleKeyConditionBuilder(List<string> sourceKeyFieldsList, List<string> referenceKeyFieldsList, DataRow sourceRow)  

filter.Condition 给出一个字符串,例如“Project_id = 255454”

【问题讨论】:

编辑您的问题并为MultipleKeyConditionBuilder提供一些启示 可以有多个条件吗?如果有多个过滤器,filter.Condition 的值是多少? 是的,它有多个条件,。视情况而定。 ' 条件 += referenceKeyFieldsList[i].ToValidSQLName() + " = " + filterChar + sourceRow[sourceKeyFieldsList[i]] + filterChar; ' 你应该看看***.com/questions/3501709/… 还有***.com/questions/848415/dynamic-where-clause-in-linq 【参考方案1】:

你可以使用这样的声明

 Func<DataRow, bool> whereClause = test => filter.Condition;

我假设filter.Condition 返回一个布尔值。我已经测试了这个简化:

 Func<DataRow, bool> whereClause = test => true;

更新

filter.Condition返回一个带有类似property = 'value'的语句的字符串。这必须使用一些函数进行评估,该函数采用该语句,插入当前 DataRow 中的值并返回一个布尔值,例如

    ...
    Func<DataRow, bool> whereClause = row => SomeClass.Evaluate(filter.Condition, row);
    ...

public static class SomeClass

     public static bool Evaluate(string expression, DataRow data)
     
          ... do some sophisticated stuff ...
          return true /  false;
     

但这个解决方案只适合直接回答问题。

我建议重新设计MultipleKeyConditionBuilder,使MultipleKeyConditionBuilder.Condition 不返回string,而是返回Predicate&lt;DataRow&gt;。之后就可以写了

Func<DataRow, bool> whereClause = test => filter.Condition(test);

【讨论】:

filter.Condition 返回一个字符串 现在只有最后一部分不同了。如何将其更改为 bool 或另一个更改为 string? MultipleKeyConditionBuilder 是如何定义的? public MultipleKeyConditionBuilder(List sourceKeyFieldsList, List referenceKeyFieldsList, DataRow sourceRow) 还有MultpileKeyConditionBuilder.Condition ?【参考方案2】:

我不知道你为什么把那里的事情复杂化。

这应该可以完成工作。

private object[] GetValueFromLookup(MultipleKeyConditionBuilder filter, string lookupValueField, DataTable datatableLookup)

    DataRow[] rows = datatableLookup.Select(filter.Condition);
    return rows.Select(r => r.Field<object>(lookupValueField)).ToArray();

【讨论】:

datatableLookup.Select 很慢。我想提高性能。这就是我使用 Linq 的原因。我试过 dataview 它也没有好处 @Masood 编辑您的问题,并对MultipleKeyConditionBuilder 有所了解。你是如何准备过滤器的? 这个函数将字符串添加到条件变量中以创建条件:它非常适合数据表选择语句,但对于 linq 它不起作用【参考方案3】:

System.Linq.Enumerable.Where 需要一个 Func&lt;T, bool&gt;(即一个将 T 作为输入并返回 bool 的函数) 对您的行 whereClause = test =&gt; filter.Condition; 工作 filter.Condition 的意义应该是 C# 代码。在您的情况下,它似乎是一个字符串。

如果我理解您在这里要做什么,那么您应该让您的 filter.Condition 返回一个 Expression&lt;Func&lt;DataRow, bool&gt;&gt;

以下是一段代码 sn-p,可帮助您了解表达式的工作原理。

        Expression<Func<string, bool>> conditionExpression = x => "MyString".Equals(x);

        // Following if block will not compile
        //if (conditionExpression("MyString")) 
        //    Console.WriteLine("True");
        //else
        //    Console.WriteLine("False");

        var condition = conditionExpression.Compile();

        // Following if block will compile.
        if(condition("MyString")) //this compiles.
            Console.WriteLine("True");
        else
            Console.WriteLine("False");

希望这会有所帮助。

【讨论】:

以上是关于C# 使用带有 where 子句的 Linq 查询作为 dataTable 上的变量的主要内容,如果未能解决你的问题,请参考以下文章

C#图解教程 第十九章 LINQ

C# LINQ 详解 From Where Select Group Into OrderBy Let Join

具有许多表、左外连接和 where 子句的 LINQ 查询

如何使用 linq lambda 扩展方法执行带有 where 子句的左外连接

带有 WHERE 子句的 SQL INNER JOIN 到 LINQ 格式

实体框架 Linq 查询:.Where 链 vs &&