I'm trying to call a function in a dynamic linq select statement, but im getting error:
No property or field 'A' exists in type 'Tuple2'
Example code:
void Main()
{
var a = new Tuple<int, int>(1,1);
var b = new[]{ a };
var q = b.AsQueryable().Select("A.Test(it.Item1)");
q.Dump();
}
public static class A
{
public static int Test(int i)
{
return i++;
}
}
How should I change my code to get this working?
If I call built in function Convert.ToInt32
for example it works fine.
var q = b.AsQueryable().Select("Convert.ToInt32(it.Item1)");
Also how do I cast a property using dynamic linq?
var q = b.AsQueryable().Select("((float)it.Item1)");
I may be confused but your syntax whereby you are using a string in your
Select
s doesn't compile for me. The following syntax works:@Armand has put together a brilliant solution for this issue, and being the only solution I was able to find regarding this I want to add to it for anyone who tries the same approach.
The class that is marked with...
... must be taken into consideration when you run the following line:
In the solution provided above, this assumes the class that contains the function to be evaluated is on the same class the code currently resides in. If the methods are to be used outside of said class, the assembly will need to change.
Nothing changes from the solution above, this is just for clarification for anyone attempting to use it.
I'll say that the
dynamic-linq
isn't "strong enough" to do these things. It looks for methods only in the given objects and some special classes:Math
,Convert
, the various base types (int
,float
,string
, ...),Guid
,Timespan
,DateTime
The list of these types is clearly visible if you use ilspy/reflector on the file. They are in
System.Linq.Dynamic.ExpressionParser.predefinedTypes
.Now, clearly I could be wrong, but this works:
.Select("Guid.NewGuid().ToString()").Cast<string>().ToArray()
showing that it's quite probable that that is the "correct" list.
There is an article here on how to modify Dynamic LINQ if you are interested http://www.krizzcode.com/2012/01/extending-dynamiclinq-language.html
Now, an intelligent man would take the source of dynamic linq and simply expand that array... But here there aren't intelligent men... There are only programmers that want blood! Blood but especially innards!
Do this (with the types you want) BEFORE the first call to Dynamic Linq (because after the first call the methods/properties of these types are cached)
Explanation: we use reflection to add our object(s) to this "special list".
I know there is already an accepted answer on this but it did not work for me. I am using Dynamic Linq 1.1.4. I wanted to do a query like this
Where GetNewestRisk() is a public method on the object represented by $. I kept getting this error "Error running query, Methods on type 'Patient' are not accessible (at index 2)".
I found in the source code there is a GlobalConfig object that allows a custom provider to be assigned which will hold all of the types you may want to work with. Here is the source code for the custom provider:
Here is how I am using it:
After making this call I am able to call methods on the objects inside of the expression.
The following works for me:
@xanatos answer doesn't work for .Net Core version. So I've found something similar related by @Kent on the System.Dynamic.Linq.Core tests DynamicExpressionParserTests written by the library's author himself.
The given
TestCustomTypeProvider
Class allows you to use theDynamicLinqType
class annotation which is pretty usefull for this problem.To answer to question, you then just needed to defined the class (ensure to annotate with DynamicLinqType) :
Add a customTypeProvider as mentioned above :
and use a ParsingConfig with the configurable Select to call it :