nreco / lambdaparser

Runtime parser for string expressions (formulas, method calls). Builds dynamic LINQ expression tree and compiles it to lambda delegate.
http://www.nrecosite.com/
MIT License
309 stars 55 forks source link

Can't read the Value ,when it is ConstantExpression . #16

Closed Jiuyong closed 5 years ago

Jiuyong commented 5 years ago

i need it ...

VitaliyMF commented 5 years ago

@Jiuyong as I remember we already discussed this in your PR (#11). If you need to traverse through Expression produced by LambdaParser and read constant values (they are wrapped with LambdaParameterWrapper internal class) I proposed to add an interface - smth like ILambdaValue - which can expose real "Value" object -- but I didn't get any confirmation that this is what you need.

Another alternative might be implementation of IConvertible for LambdaParameterWrapper class: in this case you'll able to check if Constant.Value is IConvertible, and if yes - use IConvertible.GetTypeCode and IConvertible.ToType to get real constant value.

As for me variant with IConvertible is more elegant.

Jiuyong commented 5 years ago

Yes , I need to get the real "Value" from object .

VitaliyMF commented 5 years ago

@Jiuyong just let me know if my suggestions are correct and if they solve your problem I'll include these changes into next release.

Is it enough to implement IConvertible? Or you need ILambdaValue interface to determine contants in expressions produced by LambdaParser class?

Jiuyong commented 5 years ago

by bing: I mean, I need to get the value of the correct expression so that after I parse the expression with your component, I can implement the expression myself, rather than just using it to calculate the result. So, if my translation doesn't make me ambiguous, your first implementation should be to meet my requirements. Second, I want you to parse the string as the result of the functionality of the expression, preferably an API that maintains maximum consistency with direct code definitions or generated expressions. If this can be done, then interfaces such as the IQueryable do not need to be handled separately, but are available for direct sharing. source: 我的意思是,我需要获得正确的表达式的值,以便我用你的组件解析了表达式以后,可以自己实现这个表达式,而不是仅仅使用其来计算结果。 所以,如果我的翻译没有让我歧义的话,你的第一个实现应该是满足我的要求的。 其次,我希望你将字符串解析为表达式的功能的结果,最好能和直接代码定义或者生成的表达式保持最大程度一致的API。 如果能做到这样,那么在实现 IQueryable 之类接口的时候就不需要单独处理,而是可用直接共用了。

VitaliyMF commented 5 years ago

I parse the expression with your component, I can implement the expression myself, rather than just using it to calculate the result.

ok, let's assume that you already can handle values of ConstantExpression.

I want you to parse the string as the result of the functionality of the expression, preferably an API that maintains maximum consistency with direct code definitions or generated expressions.

LambdaParser was specially designed for 'dynamic typing' - when types are aligned in run-time, and this is main reason why all constants are wrapped with internal LambdaParameterWrapper class and InvokeMethod, InvokeDelegate, InvokePropertyOrField, InvokeIndexer method calls are used instead of direct calls of methods. This approach gives great flexibility when real types of variables (expression parameters) are unknown - this is typical case when these expressions are defined by end-user.

If you need a parser that produces expression tree that 1:1 reflects what you have in string expression NReco.LambdaParser is a not right choice; take a look to https://github.com/davideicardi/DynamicExpresso

If this can be done, then interfaces such as the IQueryable do not need to be handled separately, but are available for direct sharing.

Expression produced by LambdaParser is NOT suitable for IQueryable (say, for usage as predicate in EntityFramework). You'll need to perform rather complicated 'reverse' translation to get rid of LambdaParameterWrapper, resolve real method calls instead of "InvokeMethod", "InvokeDelegate" and determine real types of variables (in other words, infer their types from context, which might be very nontrivial!) etc.

From what I see, you'll not able to use LambdaParser even if I'll add ability to access real value of ConstantExpression: resulting Expression is just not suitable for usage with IQueryable that are translated to DB queries.

VitaliyMF commented 5 years ago

Added ILambdaValue interface that can be used for accessing real constant values in Expression produced by LamdbaParser.

Shipped in 1.0.9