views:

99

answers:

2

I am having a problem converting this query via an expression tree:

WageConstIn => Convert.ToString(WageConstIn.Serialno).StartsWith("2800")

This is my expression tree:

var searchTextExp = LinqExpression.Constant("2800");
var parameterExp  = LinqExpression.Parameter(typeof(WageConstInEntity), "WageConstIn");
var propertyExp   = LinqExpression.Property(parameterExp, "Serialno");
var convertExpr   = LinqExpression.Parameter(typeof(Convert), "Convert");                   
var toStringExp   = LinqExpression.Call(convertExpr, "ToString", new[] { typeof(decimal) }, new[] { propertyExp });
var startsWithExp = LinqExpression.Call(toStringExp, "StartsWith", null, new[] { searchTextExp });

I am getting the following error:

"No method 'ToString' on type 'System.Convert' is compatible with the supplied arguments"

+1  A: 

The Convert.ToString Method (Decimal) is static (the Convert Class is a static class) and doesn't have any generic type parameters.

Use the Expression.Call Method (Type, String, Type[], Expression[]):

Creates a MethodCallExpression that represents a call to a static (Shared in Visual Basic) method by calling the appropriate factory method.

Example:

var toString = Expression.Call(typeof(Convert), "ToString", null, propertyExp);

(Also note that Convert.ToString is not generic, so you should provide null for the typeArguments parameter.)

dtb
This seems to be giving the follwing expression: ToString(WageConstIn.Serialno) instead of Convert.ToString(WageConstIn.Serialno)
Waliaula Makokha
@Waliaula Makokha: In static method call expressions the class name is not shown.
dtb
If I call this method on a property of type string like so: ToString(WageConstIn.Text) and Text is s tring i get the following error: "More than one method 'ToString' on type 'System.Convert' is compatible with the supplied arguments". How can I go about this?
Waliaula Makokha
@Waliaula Makokha: There is no Convert.ToString overload that takes a string. And it wouldn't make a lot of sense - you already have a string :-)
dtb
A: 

It is an LLBLGEN problem and I have solved it using FunctionMapping as follows:

public class FunctionMappings : FunctionMappingStore
   {
    public FunctionMappings()
        : base()
    {
        FunctionMapping mapping = new FunctionMapping(typeof(Functions), "Like", 2, "{0} LIKE {1}");
        this.Add(mapping);
    }
}

public class Functions
{
    public static bool Like(string field, string value)
    {
        return true;
    }

    public static bool Like(decimal field, string value)
    {
        return true;
    }
}

I then proceeded to call the create the linq expression as follows:

ConstantExpression searchTextExp = Expression.Constant(string.Format("{0}%", searchText));
ParameterExpression parameterExp =    Expression.Parameter(typeof(ViewWageConstInEntity), "WageConstIn");
MemberExpression propertyExp = Expression.Property(parameterExp, searchField);
MethodCallExpression likeExpr = null;

if (propertyExp.Type == typeof(decimal))
{
    likeExpr = LinqExpression.Call(
        typeof(Functions).GetMethod("Like", new[] { typeof(decimal), typeof(string) }),
                    propertyExp, searchTextExp);
}
else if (propertyExp.Type == typeof(string))
{
    likeExpr = Expression.Call(
        typeof(Functions).GetMethod("Like", new[] { typeof(string), typeof(string) }),
                    propertyExp, searchTextExp);
}

This generated the appropriate SQL in the db as follows:

WHERE ([Serialno] LIKE 'SearchText%')
Waliaula Makokha