I have an Int64 field that I want to convert in my EF Dynamic Linq query. This because I want to use teh Contains function to check if the Int64 contains a certain serie of numbers. So I use the SqlFunctions.StringConvert like
SqlFunctions.StringConvert(MyField).Contains("2012")
The Dynamic library raises a ParseException: No applicable method 'StringConvert' exists in type 'SqlFunctions'.
I changed this array in the Dynamic library so the SqlFunctions would be defined:
static readonly Type[] predefinedTypes = {
typeof(Object),
...
typeof(Math),
typeof(Convert),
typeof(EntityFunctions),
typeof(SqlFunctions)
};
Strange thing is: I also added EntityFunctions, and that works fine, exemple:
EntityFunctions.TruncateTime(LastCommentDate) = @0
UPDATE: Int64 not supported by SqlFunctions:
public static string StringConvert(decimal? number);
public static string StringConvert(double? number);
public static string StringConvert(decimal? number, int? length);
public static string StringConvert(double? number, int? length);
public static string StringConvert(decimal? number, int? length, int? decimalArg);
public static string StringConvert(double? number, int? length, int? decimalArg);
Here is what I did to get SqlFunctions.StringConvert to work in my project using the EF Dynamic Linq query extensions.
Here is a the line of code I was trying to get to work when I ran into the same issue you where having but my "Property" was an Int32 not Int64.
query.Where("SqlFunctions.StringConvert(Property).Contains(\"12\")");
I added the following line of code to the CompareConversions method
if (s == typeof (Int32) && t1 == typeof (Decimal?)) return 1;
I would guess that you would want to add a line like the following to get your code to work
if (s == typeof (Int64) && t1 == typeof (Decimal?)) return 1;
I know this looks like a hack and it is, but the issue is the library can not choose which method
public static string StringConvert(decimal? number);
public static string StringConvert(double? number);
is better, so I forced its hand (and any other method with the same signature) by making it use the conversion of Int32 to Decimal for the Expression, or in your case a Int64 to Decimal conversion.
Here is the completed method for reference
private static int CompareConversions(Type s, Type t1, Type t2)
{
if (t1 == t2) return 0;
if (s == t1) return 1;
if (s == t2) return -1;
bool t1t2 = IsCompatibleWith(t1, t2);
bool t2t1 = IsCompatibleWith(t2, t1);
if (t1t2 && !t2t1) return 1;
if (t2t1 && !t1t2) return -1;
if (IsSignedIntegralType(t1) && IsUnsignedIntegralType(t2)) return 1;
if (IsSignedIntegralType(t2) && IsUnsignedIntegralType(t1)) return -1;
// HACK: SqlFunctions.StringConvert - Force it to think the Decimal Signature
// is better than the double for Int32
if (s == typeof (Int32) && t1 == typeof (Decimal?)) return 1;
return 0;
}
Hope this helps...
I think it would be easier to first cast it to double (or decimal) as they do here and then do the conversion (you can have a possible overflow because these float types cannot handle the same amount of values as an Int64)
query.Where("SqlFunctions.StringConvert((double)Property).Contains(\"12\")");
来源:https://stackoverflow.com/questions/14828290/sqlfunctions-stringconvert-and-dynamic-linq