【问题标题】:C# Using Linq Query with where clause as variable on dataTableC# 使用带有 where 子句的 Linq 查询作为 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”

【问题讨论】:

标签: c# linq dynamic where-clause linq-to-objects


【解决方案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");

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-20
    • 1970-01-01
    相关资源
    最近更新 更多