commit 3400be98ae7ae670646c7e501ca2f592fcbb4903
parent c7692bb523fad5cdfc35c972d415d240d941266d
Author: sergik776 <sergik776@yandex.com>
Date: Sat, 11 May 2024 09:37:23 +0300
New version after publish
Diffstat:
8 files changed, 562 insertions(+), 546 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,4 +1,4 @@
-.vs/*
-QueryExpressionBuilder/bin/*
-QueryExpressionBuilder/obj/*
+.vs/*
+QueryExpressionBuilder/bin/*
+QueryExpressionBuilder/obj/*
QueryExpressionBuilder/Properties/*
\ No newline at end of file
diff --git a/.nuspec b/.nuspec
@@ -1,14 +1,13 @@
-<?xml version="1.0" encoding="utf-8"?>
-<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
- <metadata>
- <!-- Required elements-->
- <id>QueryExpressionBuilder</id>
- <version>1.0.0.0</version>
- <description>This library helps create a predicate function for filtering database queries based on a model.</description>
- <authors>Created by Taogar. </authors>
- <licenseUrl>This project is distributed under the [MIT](https://opensource.org/licenses/MIT) license, which allows free use, modification, and distribution of the code in accordance with the terms of the MIT license.</licenseUrl>
- <!-- Optional elements -->
- <!-- ... -->
- </metadata>
- <!-- Optional 'files' node -->
+<?xml version="1.0" encoding="utf-8"?>
+<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
+ <metadata>
+ <!-- Required elements-->
+ <id>QueryExpressionBuilder</id>
+ <version>1.1.0.2904</version>
+ <description>This library helps create a predicate function for filtering database queries based on a model.</description>
+ <authors>Created by Taogar. </authors>
+ <licenseUrl>This project is distributed under the [MIT](https://opensource.org/licenses/MIT) license, which allows free use, modification, and distribution of the code in accordance with the terms of the MIT license.</licenseUrl>
+ <projectUrl>Link on [GitHub](https://github.com/sergik776/QueryExpressionBuilder)</projectUrl>
+ </metadata>
+ <!-- Optional 'files' node -->
</package>
\ No newline at end of file
diff --git a/QueryExpressionBuilder.sln b/QueryExpressionBuilder.sln
@@ -1,25 +1,25 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.9.34511.98
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QueryExpressionBuilder", "QueryExpressionBuilder\QueryExpressionBuilder.csproj", "{C6B925B3-E450-4830-9B40-305102A14309}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {C6B925B3-E450-4830-9B40-305102A14309}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C6B925B3-E450-4830-9B40-305102A14309}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C6B925B3-E450-4830-9B40-305102A14309}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C6B925B3-E450-4830-9B40-305102A14309}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {7E174301-9FE3-4552-830F-D0AEB96012A0}
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34511.98
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QueryExpressionBuilder", "QueryExpressionBuilder\QueryExpressionBuilder.csproj", "{C6B925B3-E450-4830-9B40-305102A14309}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C6B925B3-E450-4830-9B40-305102A14309}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C6B925B3-E450-4830-9B40-305102A14309}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C6B925B3-E450-4830-9B40-305102A14309}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C6B925B3-E450-4830-9B40-305102A14309}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {7E174301-9FE3-4552-830F-D0AEB96012A0}
+ EndGlobalSection
+EndGlobal
diff --git a/QueryExpressionBuilder/Attributes.cs b/QueryExpressionBuilder/Attributes.cs
@@ -1,100 +1,100 @@
-namespace QueryExpressionBuilder.Attributes
-{
- /// <summary>
- /// Attribute to filtration strings
- /// </summary>
- public class String
- {
-
- /// <summary>
- /// Filtration func StartWith
- /// </summary>
- [AttributeUsage(AttributeTargets.Property)]
- public class StartWithAttribute : BasePredicateAttribute
- {
- /// <summary>
- /// Add attribute func StartWith
- /// </summary>
- /// <param name="propertyName">Name of property in DB</param>
- public StartWithAttribute(string propertyName) : base(propertyName)
- {
- }
- }
-
- /// <summary>
- /// Filtration by contains function
- /// </summary>
- public class ContainsAttribute : BasePredicateAttribute
- {
- public ContainsAttribute(string propertyName) : base (propertyName)
- {
- }
- }
- }
-
- /// <summary>
- /// Attribute to filtration numbers and DateTime
- /// </summary>
- public class Numbers
- {
- /// <summary>
- /// Filtration func GreaterOrEqual
- /// </summary>
- [AttributeUsage(AttributeTargets.Property)]
- public class GreaterOrEqualAttribute : BasePredicateAttribute
- {
- /// <summary>
- /// Add attribute func >=
- /// </summary>
- public GreaterOrEqualAttribute(string propertyName) : base(propertyName)
- {
- }
- }
-
- /// <summary>
- /// Filtration func LessOrEqual
- /// </summary>
- [AttributeUsage(AttributeTargets.Property)]
- public class LessOrEqualAttribute : BasePredicateAttribute
- {
- /// <summary>
- /// Add attribute func <=
- /// </summary>
- public LessOrEqualAttribute(string propertyName) : base(propertyName)
- {
- }
- }
-
- /// <summary>
- /// Filtration by equals function
- /// </summary>
- public class EqualsAttribute : BasePredicateAttribute
- {
- public EqualsAttribute(string propertyName) : base(propertyName)
- {
-
- }
- }
- }
-
- /// <summary>
- /// Base filtration class
- /// </summary>
- [AttributeUsage(AttributeTargets.Property)]
- public class BasePredicateAttribute : Attribute
- {
- /// <summary>
- /// Name of property in DB
- /// </summary>
- public string PropertyName { get; set; }
-
- /// <summary>
- /// Constructor with name of property in DB
- /// </summary>
- /// <param name="propertyName"></param>
- public BasePredicateAttribute(string propertyName)
- {
- PropertyName = propertyName;
- }
- }
-}
+namespace QueryExpressionBuilder.Attributes
+{
+ /// <summary>
+ /// Attribute to filtration strings
+ /// </summary>
+ public class String
+ {
+
+ /// <summary>
+ /// Filtration func StartWith
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Property)]
+ public class StartWithAttribute : BasePredicateAttribute
+ {
+ /// <summary>
+ /// Add attribute func StartWith
+ /// </summary>
+ /// <param name="propertyName">Name of property in DB</param>
+ public StartWithAttribute(string propertyName) : base(propertyName)
+ {
+ }
+ }
+
+ /// <summary>
+ /// Filtration by contains function
+ /// </summary>
+ public class ContainsAttribute : BasePredicateAttribute
+ {
+ public ContainsAttribute(string propertyName) : base (propertyName)
+ {
+ }
+ }
+ }
+
+ /// <summary>
+ /// Attribute to filtration numbers and DateTime
+ /// </summary>
+ public class Numbers
+ {
+ /// <summary>
+ /// Filtration func GreaterOrEqual
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Property)]
+ public class GreaterOrEqualAttribute : BasePredicateAttribute
+ {
+ /// <summary>
+ /// Add attribute func >=
+ /// </summary>
+ public GreaterOrEqualAttribute(string propertyName) : base(propertyName)
+ {
+ }
+ }
+
+ /// <summary>
+ /// Filtration func LessOrEqual
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Property)]
+ public class LessOrEqualAttribute : BasePredicateAttribute
+ {
+ /// <summary>
+ /// Add attribute func <=
+ /// </summary>
+ public LessOrEqualAttribute(string propertyName) : base(propertyName)
+ {
+ }
+ }
+
+ /// <summary>
+ /// Filtration by equals function
+ /// </summary>
+ public class EqualsAttribute : BasePredicateAttribute
+ {
+ public EqualsAttribute(string propertyName) : base(propertyName)
+ {
+
+ }
+ }
+ }
+
+ /// <summary>
+ /// Base filtration class
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Property)]
+ public class BasePredicateAttribute : Attribute
+ {
+ /// <summary>
+ /// Name of property in DB
+ /// </summary>
+ public string PropertyName { get; set; }
+
+ /// <summary>
+ /// Constructor with name of property in DB
+ /// </summary>
+ /// <param name="propertyName"></param>
+ public BasePredicateAttribute(string propertyName)
+ {
+ PropertyName = propertyName;
+ }
+ }
+}
diff --git a/QueryExpressionBuilder/ExpressionBuilder.cs b/QueryExpressionBuilder/ExpressionBuilder.cs
@@ -1,168 +1,168 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-using static QueryExpressionBuilder.Attributes.Numbers;
-using static QueryExpressionBuilder.Attributes.String;
-
-namespace QueryExpressionBuilder
-{
- /// <summary>
- /// Class converter from Query model with attributes to predicate func
- /// </summary>
- public static class ExpressionBuilder
- {
- /// <summary>
- /// Extension method
- /// </summary>
- /// <typeparam name="TDB">Type in DB</typeparam>
- /// <typeparam name="TQE">Type of Query object</typeparam>
- /// <param name="queryParams">Dictionary</param>
- /// <returns>Predicate func</returns>
- public static Expression<Func<TDB, bool>>? ToPredicate<TDB, TQE>(this Dictionary<string, string> queryParams)
- {
- return GetPredicateFromDictionary<TDB, TQE>(queryParams);
- }
-
- /// <summary>
- /// Make predicate from dictionary
- /// </summary>
- /// <typeparam name="TDB">Type in DB</typeparam>
- /// <typeparam name="TQE">Type of Query object</typeparam>
- /// <param name="queryParams">Dictionary</param>
- /// <returns>Predicate func</returns>
- public static Expression<Func<TDB, bool>>? GetPredicateFromDictionary<TDB, TQE>(Dictionary<string, string> queryParams)
- {
- var query = GetQueryObject<TQE>(queryParams);
- return GetPredicate<TDB, TQE>(query);
- }
-
- /// <summary>
- /// Make Query instance
- /// </summary>
- /// <typeparam name="T">Type of Query</typeparam>
- /// <param name="queryParams">Dictionary</param>
- /// <returns>Instance</returns>
- public static T GetQueryObject<T>(Dictionary<string, string> queryParams)
- {
- Type type = typeof(T);
- T queryObject = Activator.CreateInstance<T>();
-
- foreach (var property in type.GetProperties())
- {
- if (queryParams.ContainsKey(property.Name))
- {
- object value;
- Type propertyType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
-
- if (propertyType == typeof(string) && string.IsNullOrEmpty(queryParams[property.Name]))
- {
- value = null;
- }
- else
- {
- value = Convert.ChangeType(queryParams[property.Name], propertyType);
- }
-
- property.SetValue(queryObject, value);
- }
- }
-
- return queryObject;
- }
-
- /// <summary>
- /// Make new predicate func
- /// </summary>
- /// <typeparam name="TDB">Type in DB</typeparam>
- /// <typeparam name="TQE">Query type</typeparam>
- /// <returns>Predicate func</returns>
- public static Expression<Func<TDB, bool>>? GetPredicate<TDB, TQE>(TQE query)
- {
- var userParameter = Expression.Parameter(typeof(TDB), typeof(TDB).Name.ToLower());
- List<Expression> conditions = new List<Expression>();
-
- //Только те свойства которые помечены атрибутами
- var T_pr_props = typeof(TQE).GetProperties().Where(prop => prop.GetCustomAttribute<LessOrEqualAttribute>() != null ||
- prop.GetCustomAttribute<GreaterOrEqualAttribute>() != null || prop.GetCustomAttribute<StartWithAttribute>() != null ||
- prop.GetCustomAttribute<ContainsAttribute>() != null || prop.GetCustomAttribute<EqualsAttribute>() != null).ToArray();
-
- //Проходимся по всем параметрам класса БД
- foreach (var p in typeof(TDB).GetProperties())
- {
- var yslovia = T_pr_props.Where(x => x.Name.Contains(p.Name));
- foreach (var y in yslovia)
- {
- if (y.GetCustomAttribute<StartWithAttribute>() != null)
- {
- var propertyY = Expression.Property(userParameter, p.Name);
- var propertyP = Expression.Property(userParameter, p.Name);
- var containsCall = Expression.Call(propertyP, "StartsWith", null, Expression.Constant(y.GetValue(query), typeof(string)));
- var obj = y.GetValue(query);
- if (obj != null)
- {
- conditions.Add(containsCall);
- }
- }
- else if(y.GetCustomAttribute<ContainsAttribute>() != null)
- {
- var propertyY = Expression.Property(userParameter, p.Name);
- var propertyP = Expression.Property(userParameter, p.Name);
- var containsCall = Expression.Call(propertyP, "Contains", null, Expression.Constant(y.GetValue(query), typeof(string)));
- var obj = y.GetValue(query);
- if (obj != null)
- {
- conditions.Add(containsCall);
- }
- }
- else if (y.GetCustomAttribute<GreaterOrEqualAttribute>() != null)
- {
- var propertyName = y.GetCustomAttribute<GreaterOrEqualAttribute>().PropertyName;
- var propertyY = Expression.Property(userParameter, propertyName);
- var obj = y.GetValue(query);
- if (obj != null)
- {
- var value = Convert.ChangeType(obj, p.PropertyType);
- var constantValue = Expression.Constant(value, p.PropertyType);
- var condition = Expression.GreaterThanOrEqual(propertyY, constantValue);
- conditions.Add(condition);
- }
- }
- else if (y.GetCustomAttribute<LessOrEqualAttribute>() != null)
- {
- var propertyName = y.GetCustomAttribute<LessOrEqualAttribute>().PropertyName;
- var propertyY = Expression.Property(userParameter, propertyName);
- var obj = y.GetValue(query);
- if (obj != null)
- {
- var value = Convert.ChangeType(obj, p.PropertyType);
- var constantValue = Expression.Constant(value, p.PropertyType);
- var condition = Expression.LessThanOrEqual(propertyY, constantValue);
- conditions.Add(condition);
- }
- }
- else if(y.GetCustomAttribute<EqualsAttribute>() != null)
- {
- var propertyName = y.GetCustomAttribute<EqualsAttribute>().PropertyName;
- var propertyY = Expression.Property(userParameter, propertyName);
- var obj = y.GetValue(query);
- if (obj != null)
- {
- var value = Convert.ChangeType(obj, p.PropertyType);
- var constantValue = Expression.Constant(value, p.PropertyType);
- var condition = Expression.Equal(propertyY, constantValue);
- conditions.Add(condition);
- }
- }
- }
- }
-
- var body = conditions.Aggregate(Expression.AndAlso);
- var predicate = Expression.Lambda<Func<TDB, bool>>(body, userParameter);
- return predicate;
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using static QueryExpressionBuilder.Attributes.Numbers;
+using static QueryExpressionBuilder.Attributes.String;
+
+namespace QueryExpressionBuilder
+{
+ /// <summary>
+ /// Class converter from Query model with attributes to predicate func
+ /// </summary>
+ public static class ExpressionBuilder
+ {
+ /// <summary>
+ /// Extension method
+ /// </summary>
+ /// <typeparam name="TDB">Type in DB</typeparam>
+ /// <typeparam name="TQE">Type of Query object</typeparam>
+ /// <param name="queryParams">Dictionary</param>
+ /// <returns>Predicate func</returns>
+ public static Expression<Func<TDB, bool>>? ToPredicate<TDB, TQE>(this Dictionary<string, string> queryParams)
+ {
+ return GetPredicateFromDictionary<TDB, TQE>(queryParams);
+ }
+
+ /// <summary>
+ /// Make predicate from dictionary
+ /// </summary>
+ /// <typeparam name="TDB">Type in DB</typeparam>
+ /// <typeparam name="TQE">Type of Query object</typeparam>
+ /// <param name="queryParams">Dictionary</param>
+ /// <returns>Predicate func</returns>
+ public static Expression<Func<TDB, bool>>? GetPredicateFromDictionary<TDB, TQE>(Dictionary<string, string> queryParams)
+ {
+ var query = GetQueryObject<TQE>(queryParams);
+ return GetPredicate<TDB, TQE>(query);
+ }
+
+ /// <summary>
+ /// Make Query instance
+ /// </summary>
+ /// <typeparam name="T">Type of Query</typeparam>
+ /// <param name="queryParams">Dictionary</param>
+ /// <returns>Instance</returns>
+ public static T GetQueryObject<T>(Dictionary<string, string> queryParams)
+ {
+ Type type = typeof(T);
+ T queryObject = Activator.CreateInstance<T>();
+
+ foreach (var property in type.GetProperties())
+ {
+ if (queryParams.ContainsKey(property.Name))
+ {
+ object value;
+ Type propertyType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
+
+ if (propertyType == typeof(string) && string.IsNullOrEmpty(queryParams[property.Name]))
+ {
+ value = null;
+ }
+ else
+ {
+ value = Convert.ChangeType(queryParams[property.Name], propertyType);
+ }
+
+ property.SetValue(queryObject, value);
+ }
+ }
+
+ return queryObject;
+ }
+
+ /// <summary>
+ /// Make new predicate func
+ /// </summary>
+ /// <typeparam name="TDB">Type in DB</typeparam>
+ /// <typeparam name="TQE">Query type</typeparam>
+ /// <returns>Predicate func</returns>
+ public static Expression<Func<TDB, bool>>? GetPredicate<TDB, TQE>(TQE query)
+ {
+ var userParameter = Expression.Parameter(typeof(TDB), typeof(TDB).Name.ToLower());
+ List<Expression> conditions = new List<Expression>();
+
+ //Только те свойства которые помечены атрибутами
+ var T_pr_props = typeof(TQE).GetProperties().Where(prop => prop.GetCustomAttribute<LessOrEqualAttribute>() != null ||
+ prop.GetCustomAttribute<GreaterOrEqualAttribute>() != null || prop.GetCustomAttribute<StartWithAttribute>() != null ||
+ prop.GetCustomAttribute<ContainsAttribute>() != null || prop.GetCustomAttribute<EqualsAttribute>() != null).ToArray();
+
+ //Проходимся по всем параметрам класса БД
+ foreach (var p in typeof(TDB).GetProperties())
+ {
+ var yslovia = T_pr_props.Where(x => x.Name.Contains(p.Name));
+ foreach (var y in yslovia)
+ {
+ if (y.GetCustomAttribute<StartWithAttribute>() != null)
+ {
+ var obj = y.GetValue(query);
+ if (obj != null)
+ {
+ var propertyY = Expression.Property(userParameter, p.Name);
+ var propertyP = Expression.Property(userParameter, p.Name);
+ var containsCall = Expression.Call(propertyP, "StartsWith", null, Expression.Constant(y.GetValue(query), typeof(string)));
+ conditions.Add(containsCall);
+ }
+ }
+ else if(y.GetCustomAttribute<ContainsAttribute>() != null)
+ {
+ var obj = y.GetValue(query);
+ if (obj != null)
+ {
+ var propertyY = Expression.Property(userParameter, p.Name);
+ var propertyP = Expression.Property(userParameter, p.Name);
+ var containsCall = Expression.Call(propertyP, "Contains", null, Expression.Constant(y.GetValue(query), typeof(string)));
+ conditions.Add(containsCall);
+ }
+ }
+ else if (y.GetCustomAttribute<GreaterOrEqualAttribute>() != null)
+ {
+ var propertyName = y.GetCustomAttribute<GreaterOrEqualAttribute>().PropertyName;
+ var propertyY = Expression.Property(userParameter, propertyName);
+ var obj = y.GetValue(query);
+ if (obj != null)
+ {
+ var value = Convert.ChangeType(obj, p.PropertyType);
+ var constantValue = Expression.Constant(value, p.PropertyType);
+ var condition = Expression.GreaterThanOrEqual(propertyY, constantValue);
+ conditions.Add(condition);
+ }
+ }
+ else if (y.GetCustomAttribute<LessOrEqualAttribute>() != null)
+ {
+ var propertyName = y.GetCustomAttribute<LessOrEqualAttribute>().PropertyName;
+ var propertyY = Expression.Property(userParameter, propertyName);
+ var obj = y.GetValue(query);
+ if (obj != null)
+ {
+ var value = Convert.ChangeType(obj, p.PropertyType);
+ var constantValue = Expression.Constant(value, p.PropertyType);
+ var condition = Expression.LessThanOrEqual(propertyY, constantValue);
+ conditions.Add(condition);
+ }
+ }
+ else if(y.GetCustomAttribute<EqualsAttribute>() != null)
+ {
+ var propertyName = y.GetCustomAttribute<EqualsAttribute>().PropertyName;
+ var propertyY = Expression.Property(userParameter, propertyName);
+ var obj = y.GetValue(query);
+ if (obj != null)
+ {
+ var value = Convert.ChangeType(obj, p.PropertyType);
+ var constantValue = Expression.Constant(value, p.PropertyType);
+ var condition = Expression.Equal(propertyY, constantValue);
+ conditions.Add(condition);
+ }
+ }
+ }
+ }
+
+ var body = conditions.Aggregate(Expression.AndAlso);
+ var predicate = Expression.Lambda<Func<TDB, bool>>(body, userParameter);
+ return predicate;
+ }
+ }
+}
diff --git a/QueryExpressionBuilder/QueryExpressionBuilder.csproj b/QueryExpressionBuilder/QueryExpressionBuilder.csproj
@@ -1,10 +1,27 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
- <PropertyGroup>
- <TargetFramework>net8.0</TargetFramework>
- <ImplicitUsings>enable</ImplicitUsings>
- <Nullable>enable</Nullable>
- <GenerateDocumentationFile>True</GenerateDocumentationFile>
- </PropertyGroup>
-
-</Project>
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>net8.0</TargetFramework>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <Nullable>enable</Nullable>
+ <GenerateDocumentationFile>True</GenerateDocumentationFile>
+ <Version>1.1.0.2904</Version>
+ <SignAssembly>True</SignAssembly>
+ <Authors>Taogar</Authors>
+ <PackageProjectUrl></PackageProjectUrl>
+ <RepositoryUrl>https://github.com/sergik776/QueryExpressionBuilder</RepositoryUrl>
+ <AssemblyVersion>1.1.0.2904</AssemblyVersion>
+ <FileVersion>1.1.0.2904</FileVersion>
+ <PackageLicenseExpression>MIT</PackageLicenseExpression>
+ <PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
+ <PackageReadmeFile>README.md</PackageReadmeFile>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <None Include="..\README.md">
+ <Pack>True</Pack>
+ <PackagePath>\</PackagePath>
+ </None>
+ </ItemGroup>
+
+</Project>
diff --git a/QueryExpressionBuilder/QueryExpressionBuilder.csproj.user b/QueryExpressionBuilder/QueryExpressionBuilder.csproj.user
@@ -1,6 +1,6 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <_LastSelectedProfileId>P:\MyEcoSpace\Libraries\Helpers\QueryExpressionBuilder\QueryExpressionBuilder\Properties\PublishProfiles\FolderProfile.pubxml</_LastSelectedProfileId>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <_LastSelectedProfileId>P:\MyEcoSpace\Libraries\Helpers\QueryExpressionBuilder\QueryExpressionBuilder\Properties\PublishProfiles\FolderProfile.pubxml</_LastSelectedProfileId>
+ </PropertyGroup>
</Project>
\ No newline at end of file
diff --git a/README.md b/README.md
@@ -1,223 +1,223 @@
-# QueryExpressionBuilder
-Library for generating predicate functions for filtering database queries.
-
-## Description
-This library helps create a predicate function for filtering database queries based on a model.
-
-## Instruction
-To use the library, you need to create a model with properties for filtering. Properties in the model need to be marked with attributes.<br>
-
-Currently, there are 3 attributes:<br>
-
-Namespace QueryExpressionBuilder.Attributes.String - attributes for properties of type String<br>
-StartWithAttribute - Indicates that a filter equivalent to the System.String.StartWith() function will be used for the property.<br>
-ContainsAttribute - Indicates that a filter equivalent to the System.String.Contains() function will be used for the property.<br>
-
-Namespace QueryExpressionBuilder.Attributes.Numbers - attribute for all properties that are numeric, including DateTime<br>
-GreaterOrEqualAttribute - Indicates that a filter equivalent to the >= conditional expression will be used for the property.<br>
-LessOrEqualAttribute - Indicates that a filter equivalent to the <= conditional expression will be used for the property.<br>
-EqualsAttribute - Just compares values like in a function Equals.<br>
-
-You need to pass the property name from the class representing the entity in the database to the attribute constructor.
-
-## Examples
-Suppose we have an entity User, which is an entity in the database.
-```csharp
- public class User : IEntity
- {
- public Guid Id { get; set; }
- public string Name { get; set; }
- public string Surname { get; set; }
- public string Email { get; set; }
- public DateTime BirthDate { get; set; }
- public DateTime RegistrationDate { get; set; }
- public string PasswodHash { get; set; }
- public float Amount { get; set; }
- }
-```
-To create a Query filter, we need to create a query model.
-```csharp
- public class UserQuery
- {
- [QueryExpressionBuilder.Attributes.String.StartWith("Name")]
- public string? Name { get; set; }
-
- [QueryExpressionBuilder.Attributes.String.StartWith("Surname")]
- public string? Surname { get; set; }
-
- [QueryExpressionBuilder.Attributes.String.StartWith("Email")]
- public string? Email { get; set; }
-
- [QueryExpressionBuilder.Attributes.Numbers.GreaterOrEqual("BirthDate")]
- public DateTime? FromBirthDate { get; set; }
-
- [QueryExpressionBuilder.Attributes.Numbers.LessOrEqual("BirthDate")]
- public DateTime? ToBirthDate { get; set; }
-
- [QueryExpressionBuilder.Attributes.Numbers.GreaterOrEqual("RegistrationDate")]
- public DateTime? FromRegistrationDate { get; set; }
-
- [QueryExpressionBuilder.Attributes.Numbers.LessOrEqual("RegistrationDate")]
- public DateTime? ToRegistrationDate { get; set; }
-
- [QueryExpressionBuilder.Attributes.Numbers.GreaterOrEqual("Amount")]
- public float? FromAmount { get; set; }
-
- [QueryExpressionBuilder.Attributes.Numbers.LessOrEqual("Amount")]
- public float? ToAmount { get; set; }
- }
-```
-And now, in the controller method, which represents the endpoint, simply pass the UserQuery object to the ExpressionBuilder class, which will return the predicate function.
-```csharp
- [ApiController]
- [Route("[controller]")]
- public class WeatherForecastController : ControllerBase
- {
- private readonly ILogger<WeatherForecastController> _logger;
- private readonly IUserService userService;
-
- public WeatherForecastController(ILogger<WeatherForecastController> logger, IUserService _userService)
- {
- userService = _userService;
- _logger = logger;
- }
-
- /// <summary>
- /// Method for get users
- /// </summary>
- /// <param name="queryParams">Object containing filtering parameters</param>
- /// <returns>Returns a list of users</returns>
- [HttpGet("[controller]/GetUsers")]
- public async Task<IEnumerable<User>> GetUsers([FromQuery] UserQuery queryParams)
- {
- //Generating a predicate based on parameters
- var predicate = ExpressionBuilder.GetPredicate<User, UserQuery>(queryParams);
- //We pass the predicate to the service and return the result
- var result = await userService.GetUsers(predicate);
- return result;
- }
- }
-```
-Now, when sending a request to the database<br>
-https://localhost:7001/GetUsers?Name=M&FromBirthDate=2000-01-01&ToBirthDate=2040-01-01&FromAmount=1000<br>
-We get an SQL query.
-```sql
-SELECT "u"."Id", "u"."Amount", "u"."BirthDate", "u"."Email", "u"."Name", "u"."PasswodHash", "u"."RegistrationDate", "u"."Surname"
- FROM "Users" AS "u"
- WHERE instr("u"."Name", 'M') > 0 AND "u"."BirthDate" >= '2000-01-01 00:00:00' AND "u"."BirthDate" <= '2040-01-01 00:00:00' AND "u"."Amount" >= 1000
-```
-## License
-This project is distributed under the [MIT](https://opensource.org/licenses/MIT) license, which allows free use, modification, and distribution of the code in accordance with the terms of the MIT license.
-<br><br><br>
-
-# QueryExpressionBuilder
-Библиотека для генирации функций-предикатов для фильтрирования запросов в БД.
-
-## Описание
-Данная библиотека помогает создать функцию-предикат для фильтрирования запросов в БД на основе модели.
-
-## Инструкция
-Для работы библиотеки необходимо создать модель с свойствами для фильтрации.<br>
-Свойства в модели необходимо пометить атрибутами.<br>
-
-На данный момент существует 3 атрибута:<br>
-
-Пространство имен QueryExpressionBuilder.Attributes.String - атрибуты для свойств типа String<br>
-StartWithAttribute - Означает, что дял свойства будет использоватся фильтр с аналогом функции System.String.StartWith()<br>
-ContainsAttribute - Означает, что дял свойства будет использоватся фильтр с аналогом функции System.String.Contains()<br>
-
-Пространство имен QueryExpressionBuilder.Attributes.Numbers - атрибут для всех свойств которые ввляются числовыми, в том числе DateTime<br>
-GreaterOrEqualAttribute - Означает, что для свойства будет использоваться фильтр с аналогом условного выражения >=<br>
-LessOrEqualAttribute - Означает, что для свойства будет использоваться фильтр с аналогом условного выражения <=<br>
-EqualsAttribute - Просто то же самое, что и Equals.<br>
-
-В конструктор атрибута необходимо передать название свойства из класса представляющий сущьность в БД.<br>
-
-## Примеры
-Предположим у нас есть сущьность User, которая являеться сущьностью в БД.
-```csharp
- public class User : IEntity
- {
- public Guid Id { get; set; }
- public string Name { get; set; }
- public string Surname { get; set; }
- public string Email { get; set; }
- public DateTime BirthDate { get; set; }
- public DateTime RegistrationDate { get; set; }
- public string PasswodHash { get; set; }
- public float Amount { get; set; }
- }
-```
-Для создания Query фильтра нам необходимо создать query-модель
-```csharp
- public class UserQuery
- {
- [QueryExpressionBuilder.Attributes.String.StartWith("Name")]
- public string? Name { get; set; }
-
- [QueryExpressionBuilder.Attributes.String.StartWith("Surname")]
- public string? Surname { get; set; }
-
- [QueryExpressionBuilder.Attributes.String.StartWith("Email")]
- public string? Email { get; set; }
-
- [QueryExpressionBuilder.Attributes.Numbers.GreaterOrEqual("BirthDate")]
- public DateTime? FromBirthDate { get; set; }
-
- [QueryExpressionBuilder.Attributes.Numbers.LessOrEqual("BirthDate")]
- public DateTime? ToBirthDate { get; set; }
-
- [QueryExpressionBuilder.Attributes.Numbers.GreaterOrEqual("RegistrationDate")]
- public DateTime? FromRegistrationDate { get; set; }
-
- [QueryExpressionBuilder.Attributes.Numbers.LessOrEqual("RegistrationDate")]
- public DateTime? ToRegistrationDate { get; set; }
-
- [QueryExpressionBuilder.Attributes.Numbers.GreaterOrEqual("Amount")]
- public float? FromAmount { get; set; }
-
- [QueryExpressionBuilder.Attributes.Numbers.LessOrEqual("Amount")]
- public float? ToAmount { get; set; }
- }
-```
-И теперь в методе контроллера, который представляет конечную точку, нужно просто передать обьект UserQuery в класс ExpressionBuilder, который вернет функцию-предикат.
-```csharp
- [ApiController]
- [Route("[controller]")]
- public class WeatherForecastController : ControllerBase
- {
- private readonly ILogger<WeatherForecastController> _logger;
- private readonly IUserService userService;
-
- public WeatherForecastController(ILogger<WeatherForecastController> logger, IUserService _userService)
- {
- userService = _userService;
- _logger = logger;
- }
-
- /// <summary>
- /// Метод получения юзеров
- /// </summary>
- /// <param name="queryParams">Объект содержащий параметры фильтрации</param>
- /// <returns>Возвращает список юзеров</returns>
- [HttpGet("[controller]/GetUsers")]
- public async Task<IEnumerable<User>> GetUsers([FromQuery] UserQuery queryParams)
- {
- //Генерируем предикат на основе параметров
- var predicate = ExpressionBuilder.GetPredicate<User, UserQuery>(queryParams);
- //Передаем предикат в сервис и возвращаем результат
- var result = await userService.GetUsers(predicate);
- return result;
- }
- }
-```
-Теперь отправляя запрос<br>
-https://localhost:7001/GetUsers?Name=M&FromBirthDate=2000-01-01&ToBirthDate=2040-01-01&FromAmount=1000<br>
-в БД мы получаем SQL запрос
-```sql
-SELECT "u"."Id", "u"."Amount", "u"."BirthDate", "u"."Email", "u"."Name", "u"."PasswodHash", "u"."RegistrationDate", "u"."Surname"
- FROM "Users" AS "u"
- WHERE instr("u"."Name", 'M') > 0 AND "u"."BirthDate" >= '2000-01-01 00:00:00' AND "u"."BirthDate" <= '2040-01-01 00:00:00' AND "u"."Amount" >= 1000
-```
-## Лицензия
+# QueryExpressionBuilder
+Library for generating predicate functions for filtering database queries.
+
+## Description
+This library helps create a predicate function for filtering database queries based on a model.
+
+## Instruction
+To use the library, you need to create a model with properties for filtering. Properties in the model need to be marked with attributes.<br>
+
+Currently, there are 3 attributes:<br>
+
+Namespace QueryExpressionBuilder.Attributes.String - attributes for properties of type String<br>
+StartWithAttribute - Indicates that a filter equivalent to the System.String.StartWith() function will be used for the property.<br>
+ContainsAttribute - Indicates that a filter equivalent to the System.String.Contains() function will be used for the property.<br>
+
+Namespace QueryExpressionBuilder.Attributes.Numbers - attribute for all properties that are numeric, including DateTime<br>
+GreaterOrEqualAttribute - Indicates that a filter equivalent to the >= conditional expression will be used for the property.<br>
+LessOrEqualAttribute - Indicates that a filter equivalent to the <= conditional expression will be used for the property.<br>
+EqualsAttribute - Just compares values like in a function Equals.<br>
+
+You need to pass the property name from the class representing the entity in the database to the attribute constructor.
+
+## Examples
+Suppose we have an entity User, which is an entity in the database.
+```csharp
+ public class User : IEntity
+ {
+ public Guid Id { get; set; }
+ public string Name { get; set; }
+ public string Surname { get; set; }
+ public string Email { get; set; }
+ public DateTime BirthDate { get; set; }
+ public DateTime RegistrationDate { get; set; }
+ public string PasswodHash { get; set; }
+ public float Amount { get; set; }
+ }
+```
+To create a Query filter, we need to create a query model.
+```csharp
+ public class UserQuery
+ {
+ [QueryExpressionBuilder.Attributes.String.StartWith("Name")]
+ public string? Name { get; set; }
+
+ [QueryExpressionBuilder.Attributes.String.StartWith("Surname")]
+ public string? Surname { get; set; }
+
+ [QueryExpressionBuilder.Attributes.String.StartWith("Email")]
+ public string? Email { get; set; }
+
+ [QueryExpressionBuilder.Attributes.Numbers.GreaterOrEqual("BirthDate")]
+ public DateTime? FromBirthDate { get; set; }
+
+ [QueryExpressionBuilder.Attributes.Numbers.LessOrEqual("BirthDate")]
+ public DateTime? ToBirthDate { get; set; }
+
+ [QueryExpressionBuilder.Attributes.Numbers.GreaterOrEqual("RegistrationDate")]
+ public DateTime? FromRegistrationDate { get; set; }
+
+ [QueryExpressionBuilder.Attributes.Numbers.LessOrEqual("RegistrationDate")]
+ public DateTime? ToRegistrationDate { get; set; }
+
+ [QueryExpressionBuilder.Attributes.Numbers.GreaterOrEqual("Amount")]
+ public float? FromAmount { get; set; }
+
+ [QueryExpressionBuilder.Attributes.Numbers.LessOrEqual("Amount")]
+ public float? ToAmount { get; set; }
+ }
+```
+And now, in the controller method, which represents the endpoint, simply pass the UserQuery object to the ExpressionBuilder class, which will return the predicate function.
+```csharp
+ [ApiController]
+ [Route("[controller]")]
+ public class WeatherForecastController : ControllerBase
+ {
+ private readonly ILogger<WeatherForecastController> _logger;
+ private readonly IUserService userService;
+
+ public WeatherForecastController(ILogger<WeatherForecastController> logger, IUserService _userService)
+ {
+ userService = _userService;
+ _logger = logger;
+ }
+
+ /// <summary>
+ /// Method for get users
+ /// </summary>
+ /// <param name="queryParams">Object containing filtering parameters</param>
+ /// <returns>Returns a list of users</returns>
+ [HttpGet("[controller]/GetUsers")]
+ public async Task<IEnumerable<User>> GetUsers([FromQuery] UserQuery queryParams)
+ {
+ //Generating a predicate based on parameters
+ var predicate = ExpressionBuilder.GetPredicate<User, UserQuery>(queryParams);
+ //We pass the predicate to the service and return the result
+ var result = await userService.GetUsers(predicate);
+ return result;
+ }
+ }
+```
+Now, when sending a request to the database<br>
+https://localhost:7001/GetUsers?Name=M&FromBirthDate=2000-01-01&ToBirthDate=2040-01-01&FromAmount=1000<br>
+We get an SQL query.
+```sql
+SELECT "u"."Id", "u"."Amount", "u"."BirthDate", "u"."Email", "u"."Name", "u"."PasswodHash", "u"."RegistrationDate", "u"."Surname"
+ FROM "Users" AS "u"
+ WHERE instr("u"."Name", 'M') > 0 AND "u"."BirthDate" >= '2000-01-01 00:00:00' AND "u"."BirthDate" <= '2040-01-01 00:00:00' AND "u"."Amount" >= 1000
+```
+## License
+This project is distributed under the [MIT](https://opensource.org/licenses/MIT) license, which allows free use, modification, and distribution of the code in accordance with the terms of the MIT license.
+<br><br><br>
+
+# QueryExpressionBuilder
+Библиотека для генирации функций-предикатов для фильтрирования запросов в БД.
+
+## Описание
+Данная библиотека помогает создать функцию-предикат для фильтрирования запросов в БД на основе модели.
+
+## Инструкция
+Для работы библиотеки необходимо создать модель с свойствами для фильтрации.<br>
+Свойства в модели необходимо пометить атрибутами.<br>
+
+На данный момент существует 3 атрибута:<br>
+
+Пространство имен QueryExpressionBuilder.Attributes.String - атрибуты для свойств типа String<br>
+StartWithAttribute - Означает, что дял свойства будет использоватся фильтр с аналогом функции System.String.StartWith()<br>
+ContainsAttribute - Означает, что дял свойства будет использоватся фильтр с аналогом функции System.String.Contains()<br>
+
+Пространство имен QueryExpressionBuilder.Attributes.Numbers - атрибут для всех свойств которые ввляются числовыми, в том числе DateTime<br>
+GreaterOrEqualAttribute - Означает, что для свойства будет использоваться фильтр с аналогом условного выражения >=<br>
+LessOrEqualAttribute - Означает, что для свойства будет использоваться фильтр с аналогом условного выражения <=<br>
+EqualsAttribute - Просто то же самое, что и Equals.<br>
+
+В конструктор атрибута необходимо передать название свойства из класса представляющий сущьность в БД.<br>
+
+## Примеры
+Предположим у нас есть сущьность User, которая являеться сущьностью в БД.
+```csharp
+ public class User : IEntity
+ {
+ public Guid Id { get; set; }
+ public string Name { get; set; }
+ public string Surname { get; set; }
+ public string Email { get; set; }
+ public DateTime BirthDate { get; set; }
+ public DateTime RegistrationDate { get; set; }
+ public string PasswodHash { get; set; }
+ public float Amount { get; set; }
+ }
+```
+Для создания Query фильтра нам необходимо создать query-модель
+```csharp
+ public class UserQuery
+ {
+ [QueryExpressionBuilder.Attributes.String.StartWith("Name")]
+ public string? Name { get; set; }
+
+ [QueryExpressionBuilder.Attributes.String.StartWith("Surname")]
+ public string? Surname { get; set; }
+
+ [QueryExpressionBuilder.Attributes.String.StartWith("Email")]
+ public string? Email { get; set; }
+
+ [QueryExpressionBuilder.Attributes.Numbers.GreaterOrEqual("BirthDate")]
+ public DateTime? FromBirthDate { get; set; }
+
+ [QueryExpressionBuilder.Attributes.Numbers.LessOrEqual("BirthDate")]
+ public DateTime? ToBirthDate { get; set; }
+
+ [QueryExpressionBuilder.Attributes.Numbers.GreaterOrEqual("RegistrationDate")]
+ public DateTime? FromRegistrationDate { get; set; }
+
+ [QueryExpressionBuilder.Attributes.Numbers.LessOrEqual("RegistrationDate")]
+ public DateTime? ToRegistrationDate { get; set; }
+
+ [QueryExpressionBuilder.Attributes.Numbers.GreaterOrEqual("Amount")]
+ public float? FromAmount { get; set; }
+
+ [QueryExpressionBuilder.Attributes.Numbers.LessOrEqual("Amount")]
+ public float? ToAmount { get; set; }
+ }
+```
+И теперь в методе контроллера, который представляет конечную точку, нужно просто передать обьект UserQuery в класс ExpressionBuilder, который вернет функцию-предикат.
+```csharp
+ [ApiController]
+ [Route("[controller]")]
+ public class WeatherForecastController : ControllerBase
+ {
+ private readonly ILogger<WeatherForecastController> _logger;
+ private readonly IUserService userService;
+
+ public WeatherForecastController(ILogger<WeatherForecastController> logger, IUserService _userService)
+ {
+ userService = _userService;
+ _logger = logger;
+ }
+
+ /// <summary>
+ /// Метод получения юзеров
+ /// </summary>
+ /// <param name="queryParams">Объект содержащий параметры фильтрации</param>
+ /// <returns>Возвращает список юзеров</returns>
+ [HttpGet("[controller]/GetUsers")]
+ public async Task<IEnumerable<User>> GetUsers([FromQuery] UserQuery queryParams)
+ {
+ //Генерируем предикат на основе параметров
+ var predicate = ExpressionBuilder.GetPredicate<User, UserQuery>(queryParams);
+ //Передаем предикат в сервис и возвращаем результат
+ var result = await userService.GetUsers(predicate);
+ return result;
+ }
+ }
+```
+Теперь отправляя запрос<br>
+https://localhost:7001/GetUsers?Name=M&FromBirthDate=2000-01-01&ToBirthDate=2040-01-01&FromAmount=1000<br>
+в БД мы получаем SQL запрос
+```sql
+SELECT "u"."Id", "u"."Amount", "u"."BirthDate", "u"."Email", "u"."Name", "u"."PasswodHash", "u"."RegistrationDate", "u"."Surname"
+ FROM "Users" AS "u"
+ WHERE instr("u"."Name", 'M') > 0 AND "u"."BirthDate" >= '2000-01-01 00:00:00' AND "u"."BirthDate" <= '2040-01-01 00:00:00' AND "u"."Amount" >= 1000
+```
+## Лицензия
Этот проект распространяется под лицензией [MIT](https://opensource.org/licenses/MIT), которая разрешает свободное использование, изменение и распространение кода в соответствии с условиями лицензии MIT.
\ No newline at end of file