1

When using Linq to Entities, the resulting query should run on sql server (not enumerating it into memory and then perform the conversion)

I currently have a project whereby I build expression trees for string searching. I am currently exploring the possibility of converting non string properties to strings to enable searching on primitive types, such as integer and Guid etc.

I currently try to Convert a supplied lamda property to a string and then swap it into the expression tree using the following:

var stringProperty = Expression.Convert(property.Body, typeof (string));

System.InvalidOperationException : No coercion operator is defined between types 'System.Int32' and 'System.String'.

Am I trying to achieve the impossible or is there a way to extend linq to entities to support conversions?

NinjaNye
  • 7,046
  • 1
  • 32
  • 46
  • Possible duplicate of [LINQ Expression Conversion / Concat from Int to string](http://stackoverflow.com/questions/17862314/linq-expression-conversion-concat-from-int-to-string) – xZ6a33YaYEfmv Oct 01 '15 at 09:38
  • It is indeed similar but the solution they have is not compatible with linq to entities unfortunately – NinjaNye Oct 01 '15 at 09:40
  • there's [SqlFunctions.StringConvert](https://msdn.microsoft.com/en-us/library/system.data.objects.sqlclient.sqlfunctions.stringconvert(v=vs.110).aspx) but it seems that it accepts only `Nullable`. – xZ6a33YaYEfmv Oct 01 '15 at 09:47
  • quick search showed that convert `Guid` to string is impossible with Linq to entities for now; regarding `integer` `SqlFunctions.StringConvert` should do the trick. Example of usage see [here](http://stackoverflow.com/a/3292773/183267). It might be possible to convert to Expression version. – xZ6a33YaYEfmv Oct 01 '15 at 09:51

1 Answers1

1

The basic ideea is that Expression.Convert will be emitted in MSIL as a classical convert simmilar to this code (imagine that your property type is an int):

int value = 80;
string result = (string)value;

This operation obviouslly is not supported, so neither will be in your case. Alternatives:

I assume that you already have a variable, let's call that variable "property" of type MemberExpression (represents your property in an expression-like fashion).

1) Try to make a special static method convertor (an universal convertor):

public class UniversalConvertor {
     public static string Convert (object o) {
       return ... some convert logic ... :)
     }
} 

...

MethodInfo minfo = typeof (UniversalConvertor).GetMethod ("Convert", BindingFlags.Static | BindingFlags.Public);

var stringProperty = Expression.Call (null, minfo, property);

2) Try to call the "Convert.ToString" API:

MethodInfo minfo = typeof(Convert).GetMethod("ToString", BindingFlags.Static | BindingFlags.Public, Type.DefaultBinder, new Type[] { property.Type }, null);

var stringProperty = Expression.Call (null, minfo, property); // here we are calling the coresponding "Convert" method for the actually property type.

You could combine both methods: For property types that are known by the Convert.ToString API, you can use the second method. If not, you can make a fallback on the more generic method written by you. Feel free to implement as you like.

George Lica
  • 1,798
  • 1
  • 12
  • 23