Call function in dynamic linq

后端 未结 7 838
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-31 21:13

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\'
相关标签:
7条回答
  • 2020-12-31 21:45

    @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...

    [DynamicLinqType] 
    

    ... must be taken into consideration when you run the following line:

    FindTypesMarkedWithDynamicLinqTypeAttribute(new[] { GetType().GetTypeInfo().Assembly })
    

    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.

    FindTypesMarkedWithDynamicLinqTypeAttribute(new[] { typeof(AnotherClassName).Assembly })
    

    Nothing changes from the solution above, this is just for clarification for anyone attempting to use it.

    0 讨论(0)
  • 2020-12-31 21:47

    @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 TestCustomTypeProviderClass allows you to use the DynamicLinqType 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) :

    [DynamicLinqType] 
    public static class A
    {
       public static int Test(int i)
       {
          return i++;
       }
    }
    

    Add a customTypeProvider as mentioned above :

    private class TestCustomTypeProvider : AbstractDynamicLinqCustomTypeProvider, IDynamicLinkCustomTypeProvider
    {
       private HashSet<Type> _customTypes;
    
       public virtual HashSet<Type> GetCustomTypes()
       {
          if (_customTypes != null)
          {
              return _customTypes;
          }
    
          _customTypes = new HashSet<Type>(FindTypesMarkedWithDynamicLinqTypeAttribute(new[] { GetType().GetTypeInfo().Assembly }));
                return _customTypes;
        }
    }
    

    and use a ParsingConfig with the configurable Select to call it :

    var config = new ParsingConfig
    {
         CustomTypeProvider = new TestCustomTypeProvider()
    };
    
    var q = b.AsQueryable().Select(config, "A.Test(it.Item1)");
    
    0 讨论(0)
  • 2020-12-31 21:48

    The following works for me:

    var a = new Tuple<int, int>(1, 1);
    var b = new[] { a };
    var q = b.AsQueryable().Select(it=>A.Test(it.Item1));
    var q1 = b.AsQueryable().Select(it => Convert.ToInt32(it.Item1));
    var q2 = b.AsQueryable().Select(it => (float) it.Item1);
    
    0 讨论(0)
  • 2020-12-31 21:52
    var b = new[]{ a };
    

    The above array is don't know what type of array , and it's not type safe ?

    Your values are assigned in variant data type so it's not integer value (I think string value) ,when you get this values in your query must need to convert.toint32() because your class parameter data type is integer

    Please try it

     var b = new **int**[]{ a }; 
    

    instead of var b = new[]{ a };

    The important hint is here (in bold):

    No property or field 'xxx' exists in **type** 'xxx'
    

    And Please look this for previous discussion :

    Dynamic Linq - no property or field exists in type 'datarow'

    0 讨论(0)
  • 2020-12-31 21:58

    I may be confused but your syntax whereby you are using a string in your Selects doesn't compile for me. The following syntax works:

    var q = b.AsQueryable().Select(it => A.Test(it.Item1));
    
    0 讨论(0)
  • 2020-12-31 22:05

    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

    $.GetNewestRisk() == null
    

    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:

    public class CustomTypeProvider: IDynamicLinkCustomTypeProvider
    {
        public HashSet<Type> GetCustomTypes()
        {
            HashSet<Type> types = new HashSet<Type>();
            types.Add(typeof(Patient));
            types.Add(typeof(RiskFactorResult));
            types.Add(typeof(PatientLabResult));
            types.Add(typeof(PatientVital));
            return types;
        }
    }
    

    Here is how I am using it:

    System.Linq.Dynamic.GlobalConfig.CustomTypeProvider = new CustomType();
    

    After making this call I am able to call methods on the objects inside of the expression.

    0 讨论(0)
提交回复
热议问题