1

I have seen different examples and questions but I cannot figure how to write this query successfully. The where clause condition is in 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();

    }

I am getting this error. I have tried different things but unfortunately I cannot understand how to solve it.

cannot convert from 'System.func (int,string)' to 'System.func(system.Data.DataRow,int,bool)'

MultipleKeyConditionBuilder.This function gives the filter condition. It is defined as.

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

filter.Condition gives a string for example "Project_id = 255454"

مسعود
  • 679
  • 10
  • 25

3 Answers3

1

You can use a declaration like this

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

I assume that filter.Condition returns a boolean value. I have tested this simplification:

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

Update:

filter.Conditionreturns a string with statements like property = 'value'. This has to evaluated with some function that takes this statement, inserts the values from the current DataRow and returns a boolean, like

    ...
    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;
     }
}

But this solution is only fitting to give a direct answer to the question.

I suggest the redesign the MultipleKeyConditionBuilder that MultipleKeyConditionBuilder.Condition does not return a string but a Predicate<DataRow>. After that you can write

Func<DataRow, bool> whereClause = test => filter.Condition(test);
Ralf Bönning
  • 14,515
  • 5
  • 49
  • 67
0

I don't know why you have complicated the things there.

This should do the job.

private object[] GetValueFromLookup(MultipleKeyConditionBuilder filter, string lookupValueField, DataTable datatableLookup)
{
    DataRow[] rows = datatableLookup.Select(filter.Condition);
    return rows.Select(r => r.Field<object>(lookupValueField)).ToArray();
}
Sarvesh Mishra
  • 2,014
  • 15
  • 30
  • The datatableLookup.Select is slow. I want to improve the performance. That's why I am using Linq. I tried dataview it was also not beneficial – مسعود Sep 05 '16 at 11:57
  • @Masood Edit your question and throw some light on `MultipleKeyConditionBuilder`. How you are preparing the filter? – Sarvesh Mishra Sep 05 '16 at 12:08
  • This function is adding strings to condition variable to make a condition: it is perfect for data table select statement but for linq its not working – مسعود Sep 05 '16 at 12:17
0

System.Linq.Enumerable.Where expects a Func<T, bool> (i.e. a function that takes T as input and returns bool) meaning for your line whereClause = test => filter.Condition; to work filter.Condition should be C# code. In your case it seems to be a string.

If I understand what you are trying to do here then you should have your filter.Condition return an Expression<Func<DataRow, bool>>.

Following is a code snippet to help you understand how Expressions work.

        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");

Hope this helps.

Parag Patil
  • 156
  • 7