Skip to content

Commit 583da58

Browse files
authored
Merge pull request #11 from jzarob/master
Updated query builder with support for indexed properties.
2 parents 4756e18 + 0b2b852 commit 583da58

File tree

4 files changed

+69
-15
lines changed

4 files changed

+69
-15
lines changed

Castle.DynamicLinqQueryBuilder.Tests/Castle.DynamicLinqQueryBuilder.Tests.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<WarningLevel>4</WarningLevel>
3131
</PropertyGroup>
3232
<ItemGroup>
33-
<Reference Include="nunit.framework, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
33+
<Reference Include="nunit.framework, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
3434
<HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
3535
<Private>True</Private>
3636
</Reference>
@@ -69,4 +69,4 @@
6969
<Target Name="AfterBuild">
7070
</Target>
7171
-->
72-
</Project>
72+
</Project>

Castle.DynamicLinqQueryBuilder.Tests/Tests.cs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Runtime.Serialization;
77
using System.Text;
88
using System.Threading.Tasks;
9+
910
using NUnit.Framework;
1011

1112
namespace Castle.DynamicLinqQueryBuilder.Tests
@@ -3167,10 +3168,41 @@ public void FilterWithInvalidParameters()
31673168
contentIdFilter.Rules.First().Type = "integer";
31683169
contentIdFilter.Rules.First().Operator = "NOT_AN_OPERATOR";
31693170
startingQuery.BuildQuery<ExpressionTreeBuilderTestClass>(contentIdFilter).ToList();
3170-
31713171
});
31723172
}
31733173

3174+
private class IndexedClass
3175+
{
3176+
int this[string someIndex]
3177+
{
3178+
get
3179+
{
3180+
return 2;
3181+
}
3182+
}
3183+
}
3184+
3185+
[Test]
3186+
public void IndexedExpression_Test()
3187+
{
3188+
var rule = new FilterRule
3189+
{
3190+
Condition = "and",
3191+
Field = "ContentTypeId",
3192+
Id = "ContentTypeId",
3193+
Input = "NA",
3194+
Operator = "equal",
3195+
Type = "integer",
3196+
Value = "2"
3197+
};
3198+
3199+
var result = new[] { new IndexedClass() }.BuildQuery(rule, true, "Item");
3200+
Assert.IsTrue(result.Any());
3201+
3202+
rule.Value = "3";
3203+
result = new[] { new IndexedClass() }.BuildQuery(rule, true, "Item");
3204+
Assert.IsFalse(result.Any());
3205+
}
31743206
#endregion
31753207

31763208
#region Column Definition Builder

Castle.DynamicLinqQueryBuilder.sln

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 14
4-
VisualStudioVersion = 14.0.24720.0
4+
VisualStudioVersion = 14.0.25420.1
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Castle.DynamicLinqQueryBuilder", "Castle.DynamicLinqQueryBuilder\Castle.DynamicLinqQueryBuilder.csproj", "{C73EA60C-7046-4665-8A79-0E2AA85C43EC}"
77
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Castle.DynamicLinqQueryBuilder.Tests", "Castle.DynamicLinqQueryBuilder.Tests\Castle.DynamicLinqQueryBuilder.Tests.csproj", "{AA125B72-F684-4DF0-803D-7CE45C0B915F}"
9+
EndProject
810
Global
911
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1012
Debug|Any CPU = Debug|Any CPU
@@ -15,6 +17,10 @@ Global
1517
{C73EA60C-7046-4665-8A79-0E2AA85C43EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
1618
{C73EA60C-7046-4665-8A79-0E2AA85C43EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
1719
{C73EA60C-7046-4665-8A79-0E2AA85C43EC}.Release|Any CPU.Build.0 = Release|Any CPU
20+
{AA125B72-F684-4DF0-803D-7CE45C0B915F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{AA125B72-F684-4DF0-803D-7CE45C0B915F}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{AA125B72-F684-4DF0-803D-7CE45C0B915F}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{AA125B72-F684-4DF0-803D-7CE45C0B915F}.Release|Any CPU.Build.0 = Release|Any CPU
1824
EndGlobalSection
1925
GlobalSection(SolutionProperties) = preSolution
2026
HideSolutionNode = FALSE

Castle.DynamicLinqQueryBuilder/QueryBuilder.cs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ public static class QueryBuilder
2828
/// <typeparam name="T">The generic type.</typeparam>
2929
/// <param name="queryable">The queryable.</param>
3030
/// <param name="filterRule">The filter rule.</param>
31+
/// <param name="useIndexedProperty">Whether or not to use indexed property</param>
32+
/// <param name="indexedPropertyName">The indexable property to use</param>
3133
/// <returns>Filtered IQueryable</returns>
32-
public static IQueryable<T> BuildQuery<T>(this IEnumerable<T> queryable, FilterRule filterRule)
34+
public static IQueryable<T> BuildQuery<T>(this IEnumerable<T> queryable, FilterRule filterRule, bool useIndexedProperty = false, string indexedPropertyName = null)
3335
{
3436
string parsedQuery;
35-
return BuildQuery(queryable.AsQueryable(), filterRule, out parsedQuery);
37+
return BuildQuery(queryable.AsQueryable(), filterRule, out parsedQuery, useIndexedProperty, indexedPropertyName);
3638
}
3739

3840
/// <summary>
@@ -41,11 +43,13 @@ public static IQueryable<T> BuildQuery<T>(this IEnumerable<T> queryable, FilterR
4143
/// <typeparam name="T">The generic type.</typeparam>
4244
/// <param name="queryable">The queryable.</param>
4345
/// <param name="filterRule">The filter rule.</param>
46+
/// <param name="useIndexedProperty">Whether or not to use indexed property</param>
47+
/// <param name="indexedPropertyName">The indexable property to use</param>
4448
/// <returns>Filtered IQueryable</returns>
45-
public static IQueryable<T> BuildQuery<T>(this IList<T> queryable, FilterRule filterRule)
49+
public static IQueryable<T> BuildQuery<T>(this IList<T> queryable, FilterRule filterRule, bool useIndexedProperty = false, string indexedPropertyName = null)
4650
{
4751
string parsedQuery;
48-
return BuildQuery(queryable.AsQueryable(), filterRule, out parsedQuery);
52+
return BuildQuery(queryable.AsQueryable(), filterRule, out parsedQuery, useIndexedProperty, indexedPropertyName);
4953
}
5054

5155
/// <summary>
@@ -54,11 +58,13 @@ public static IQueryable<T> BuildQuery<T>(this IList<T> queryable, FilterRule fi
5458
/// <typeparam name="T">The generic type.</typeparam>
5559
/// <param name="queryable">The queryable.</param>
5660
/// <param name="filterRule">The filter rule.</param>
61+
/// <param name="useIndexedProperty">Whether or not to use indexed property</param>
62+
/// <param name="indexedPropertyName">The indexable property to use</param>
5763
/// <returns>Filtered IQueryable</returns>
58-
public static IQueryable<T> BuildQuery<T>(this IQueryable<T> queryable, FilterRule filterRule)
64+
public static IQueryable<T> BuildQuery<T>(this IQueryable<T> queryable, FilterRule filterRule, bool useIndexedProperty = false, string indexedPropertyName = null)
5965
{
6066
string parsedQuery;
61-
return BuildQuery(queryable, filterRule, out parsedQuery);
67+
return BuildQuery(queryable, filterRule, out parsedQuery, useIndexedProperty, indexedPropertyName);
6268
}
6369

6470
/// <summary>
@@ -69,8 +75,10 @@ public static IQueryable<T> BuildQuery<T>(this IQueryable<T> queryable, FilterRu
6975
/// <param name="queryable">The queryable.</param>
7076
/// <param name="filterRule">The filter rule.</param>
7177
/// <param name="parsedQuery">The parsed query.</param>
78+
/// <param name="useIndexedProperty">Whether or not to use indexed property</param>
79+
/// <param name="indexedPropertyName">The indexable property to use</param>
7280
/// <returns>Filtered IQueryable.</returns>
73-
public static IQueryable<T> BuildQuery<T>(this IQueryable<T> queryable, FilterRule filterRule, out string parsedQuery)
81+
public static IQueryable<T> BuildQuery<T>(this IQueryable<T> queryable, FilterRule filterRule, out string parsedQuery, bool useIndexedProperty = false, string indexedPropertyName = null)
7482
{
7583
if (filterRule == null)
7684
{
@@ -80,7 +88,7 @@ public static IQueryable<T> BuildQuery<T>(this IQueryable<T> queryable, FilterRu
8088

8189
var pe = Expression.Parameter(typeof(T), "item");
8290

83-
var expressionTree = BuildExpressionTree(pe, filterRule);
91+
var expressionTree = BuildExpressionTree(pe, filterRule, useIndexedProperty, indexedPropertyName);
8492
if (expressionTree == null)
8593
{
8694
parsedQuery = "";
@@ -102,13 +110,13 @@ public static IQueryable<T> BuildQuery<T>(this IQueryable<T> queryable, FilterRu
102110

103111
}
104112

105-
private static Expression BuildExpressionTree(ParameterExpression pe, FilterRule rule)
113+
private static Expression BuildExpressionTree(ParameterExpression pe, FilterRule rule, bool useIndexedProperty = false, string indexedPropertyName = null)
106114
{
107115

108116
if (rule.Rules != null && rule.Rules.Any())
109117
{
110118
var expressions =
111-
rule.Rules.Select(childRule => BuildExpressionTree(pe, childRule))
119+
rule.Rules.Select(childRule => BuildExpressionTree(pe, childRule, useIndexedProperty, indexedPropertyName))
112120
.Where(expression => expression != null)
113121
.ToList();
114122

@@ -151,7 +159,15 @@ private static Expression BuildExpressionTree(ParameterExpression pe, FilterRule
151159
throw new Exception($"Unexpected data type {rule.Type}");
152160
}
153161

154-
var propertyExp = Expression.Property(pe, rule.Field);
162+
Expression propertyExp = null;
163+
if (useIndexedProperty)
164+
{
165+
propertyExp = Expression.Property(pe, indexedPropertyName, Expression.Constant(rule.Field));
166+
}
167+
else
168+
{
169+
propertyExp = Expression.Property(pe, rule.Field);
170+
}
155171

156172
Expression expression;
157173

0 commit comments

Comments
 (0)