Afk.Expression
2.4.0
dotnet add package Afk.Expression --version 2.4.0
NuGet\Install-Package Afk.Expression -Version 2.4.0
<PackageReference Include="Afk.Expression" Version="2.4.0" />
paket add Afk.Expression --version 2.4.0
#r "nuget: Afk.Expression, 2.4.0"
// Install Afk.Expression as a Cake Addin #addin nuget:?package=Afk.Expression&version=2.4.0 // Install Afk.Expression as a Cake Tool #tool nuget:?package=Afk.Expression&version=2.4.0
Expression
Afk.Expression is an expression parser/evaluation. Expression is parse only once and use to evaluate differents inputs (variables, constants, functions). This library can be used to generate SQL Expression to be used with Entity Framework.
Version
The library is compatible with netstandard2.0
NUGET
The easiest way to install is by using NuGet.
HowTo
This library allows you to enter complex expressions which will be evaluated and calculated on demand.
ExpressionEval eval = new ExpressionEval("5 * (3 + 8)");
Console.WriteLine(eval.Evaluate());
>>> 55
String and boolean expression can be evaluated too
ExpressionEval eval = new ExpressionEval("'one ' + 'and' + ' two'");
Console.WriteLine(eval.Evaluate());
>>> one and two
ExpressionEval eval = new ExpressionEval("true or false");
Console.WriteLine(eval.Evaluate());
>>> true
Operators
By default the ^ is the logical exclusive OR operator. You can change its behavior by using the operator type Arithmetic
ExpressionEval eval = new ExpressionEval("4^2", OperatorType.Arithmetic);
Console.WriteLine(eval.Evaluate());
>>> 16
Dates
Use the function @D to specify date with the format YYYY-MM-DD HH:MM:SS. You can specify AM and PM indicator too.
ExpressionEval eval = new ExpressionEval("@D(2022-03-08) + 1", OperatorType.Arithmetic);
Console.WriteLine(eval.Evaluate());
>>> 09/03/2022 00:00:00
Add and substract a number of whole and fractional days with operators + and -
@D(2022-08-05) + 1.5
@D(2022-08-05) - 7
Variables
Expression allows you to use variables evaluated on execution
ExpressionEval eval = new ExpressionEval("5 * x2 + y");
eval.AddVariable("x"); eval.AddVariable("y");
eval.UserExpressionEventHandler += (s, e) => {
if (e.Name == "x")
e.Result = 8d;
else if (e.Name == "y")
e.Result = 5d;
};
Console.WriteLine(eval.Evaluate());
>>> 325
Constants
Constants can be added to the expression
ExpressionEval eval = new ExpressionEval("pi");
eval.AddConstant("pi", 3.14);
Console.WriteLine(eval.Evaluate());
>>> 3.14
Functions
External function can be defined
private void OnFunctionHandler(object sender, UserFunctionEventArgs e)
{
if (e.Name == "Concat")
{
e.Result = string.Join("", e.Parameters);
}
}
ExpressionEval eval = new ExpressionEval("Concat('The ', 'dogs ', 'barks') + '.'");
eval.AddFunctions("Concat");
eval.UserFunctionEventHandler += OnFunctionHandler;
Console.WriteLine(eval.Evaluate());
>>> The dogs barks
Custom operand
You can define custom operand to intercept binary operation on user expression if default operation don't meet your needs.
class CustomStringOperand : ICustomOperand
{
private readonly string customValue;
public CustomStringOperand(string customValue)
{
this.customValue = customValue;
}
public object HandleOperation(string @operator, object otherOperand, bool isLeftOperand)
{
if (@operator == "+" && otherOperand != null)
{
return (isLeftOperand) ? $"{customValue}/{otherOperand}" : $"{otherOperand}/{customValue}";
}
return string.Empty;
}
}
private void OnFunctionHandler(object sender, UserFunctionEventArgs e)
{
if (e.Name == "val1")
{
e.Result = new CustomStringOperand("dogs");
}
}
ExpressionEval eval = new ExpressionEval("val1 + 'cats'");
eval.UserFunctionEventHandler += OnFunctionHandler;
Console.WriteLine(eval.Evaluate());
>>> dogs/cats
EF Core
Expression can be used to generate System.Linq.Expressions.Expression to request DbContext. You need to define a ILambdaExpressionProvider which provides expression on your entity.
class MyLambdaProvider : ILambdaExpressionProvider
{
public Expression GetExpression(ParameterExpression parameter, string propertyName)
{
if (propertyName.Equals("Name", StringComparison.InvariantCultureIgnoreCase))
{
return System.Linq.Expressions.Expression.Property(parameter, nameof(Student.Name));
}
else if (propertyName.Equals("Age", StringComparison.InvariantCultureIgnoreCase))
{
...
}
return null;
}
Gets the expression with the extension method ToLambda on your expression :
ExpressionEval eval = new ExpressionEval("name='john'", CaseSensitivity.None);
eval.UserExpressionEventHandler += evalProperties.Evaluate;
var lambda = eval.ToLambda<Student, bool>(new MyLambdaProvider());
var result = myContext.Students.Where(lambda).ToList();
Overide operators
The ILambdaExpressionProvider enables you to override operators.
By default the like operator use the Contains method translate to CHARINDEX sql function. To overide this operator use the following definition :
class MyLambdaProvider : ILambdaExpressionProvider
{
public Expression GetExpression(Expression left, string operand, Expression right)
{
if (operand == "like")
{
var method = typeof(DbFunctionsExtensions).GetMethod("Like", new[] { typeof(DbFunctions), typeof(string), typeof(string) });
MethodCallExpression like = System.Linq.Expressions.Expression.Call(method, Expression.Constant(EF.Functions), left, right);
return like;
}
return null;
}
}
ExpressionEval eval = new ExpressionEval("name like '8000%'", CaseSensitivity.None);
eval.UserExpressionEventHandler += evalProperties.Evaluate;
var lambda = eval.ToLambda<Student, bool>(new MyLambdaProvider());
Console.WriteLine(lambda.ToString());
>>> "s => value(Microsoft.EntityFrameworkCore.DbFunctions).Like(s.Name, \"8000%\")"
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
2.4.0 | 60 | 11/20/2024 |
2.3.0 | 1,431 | 1/28/2023 |
2.2.0 | 300 | 1/28/2023 |
2.1.0 | 322 | 12/30/2022 |
2.0.0 | 1,415 | 9/4/2021 |
1.3.5 | 2,222 | 7/24/2020 |
1.3.4 | 1,971 | 2/12/2020 |
1.3.3 | 792 | 2/7/2020 |
1.3.2 | 867 | 8/29/2019 |
1.3.1 | 1,578 | 8/16/2019 |
1.3.0 | 655 | 8/7/2019 |
1.2.0 | 618 | 8/6/2019 |
1.1.0 | 692 | 7/8/2019 |
1.0.0 | 3,220 | 8/17/2017 |