Skip to content
This repository was archived by the owner on Feb 17, 2025. It is now read-only.

Commit 888ec1b

Browse files
author
Ihar Yakimush
committed
fix validators
1 parent 253c1f1 commit 888ec1b

File tree

3 files changed

+112
-100
lines changed

3 files changed

+112
-100
lines changed

Community.Data.OData.Linq/Community.OData.Linq.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
<Description>Use OData filter text query in linq expresson for any IQuerable without ASP.NET dependency</Description>
1616
<Company />
1717
<RepositoryUrl></RepositoryUrl>
18-
<Version>1.0.1</Version>
18+
<Version>1.0.2</Version>
1919
<NeutralLanguage>en</NeutralLanguage>
20+
<AssemblyVersion>1.0.2.0</AssemblyVersion>
21+
<FileVersion>1.0.2.0</FileVersion>
2022
</PropertyGroup>
2123

2224
<ItemGroup>
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
namespace Community.OData.Linq.OData.Query.Expressions
2+
{
3+
using System.Collections.Generic;
4+
using System.Diagnostics.Contracts;
5+
using System.Linq;
6+
using System.Linq.Expressions;
7+
8+
using Community.OData.Linq.Common;
9+
using Community.OData.Linq.Properties;
10+
11+
using Microsoft.OData;
12+
using Microsoft.OData.Edm;
13+
using Microsoft.OData.UriParser;
14+
15+
public static class OrderByBinder
16+
{
17+
public static IOrderedQueryable OrderApplyToCore<T>(ODataQuery<T> query, ODataQuerySettings querySettings, ICollection<OrderByNode> nodes, IEdmModel model)
18+
{
19+
bool alreadyOrdered = false;
20+
IQueryable querySoFar = query;
21+
22+
HashSet<object> propertiesSoFar = new HashSet<object>();
23+
HashSet<string> openPropertiesSoFar = new HashSet<string>();
24+
bool orderByItSeen = false;
25+
26+
foreach (OrderByNode node in nodes)
27+
{
28+
OrderByPropertyNode propertyNode = node as OrderByPropertyNode;
29+
OrderByOpenPropertyNode openPropertyNode = node as OrderByOpenPropertyNode;
30+
31+
if (propertyNode != null)
32+
{
33+
// Use autonomy class to achieve value equality for HasSet.
34+
var edmPropertyWithPath = new { propertyNode.Property, propertyNode.PropertyPath };
35+
OrderByDirection direction = propertyNode.Direction;
36+
37+
// This check prevents queries with duplicate properties (e.g. $orderby=Id,Id,Id,Id...) from causing stack overflows
38+
if (propertiesSoFar.Contains(edmPropertyWithPath))
39+
{
40+
throw new ODataException(Error.Format(SRResources.OrderByDuplicateProperty, edmPropertyWithPath.PropertyPath));
41+
}
42+
43+
propertiesSoFar.Add(edmPropertyWithPath);
44+
45+
if (propertyNode.OrderByClause != null)
46+
{
47+
querySoFar = AddOrderByQueryForProperty(query, querySettings, propertyNode.OrderByClause, querySoFar, direction, alreadyOrdered);
48+
}
49+
else
50+
{
51+
querySoFar = ExpressionHelpers.OrderByProperty(querySoFar, model, edmPropertyWithPath.Property, direction, typeof(T), alreadyOrdered);
52+
}
53+
54+
alreadyOrdered = true;
55+
}
56+
else if (openPropertyNode != null)
57+
{
58+
// This check prevents queries with duplicate properties (e.g. $orderby=Id,Id,Id,Id...) from causing stack overflows
59+
if (openPropertiesSoFar.Contains(openPropertyNode.PropertyName))
60+
{
61+
throw new ODataException(Error.Format(SRResources.OrderByDuplicateProperty, openPropertyNode.PropertyPath));
62+
}
63+
64+
openPropertiesSoFar.Add(openPropertyNode.PropertyName);
65+
Contract.Assert(openPropertyNode.OrderByClause != null);
66+
querySoFar = AddOrderByQueryForProperty(query, querySettings, openPropertyNode.OrderByClause, querySoFar, openPropertyNode.Direction, alreadyOrdered);
67+
alreadyOrdered = true;
68+
}
69+
else
70+
{
71+
// This check prevents queries with duplicate nodes (e.g. $orderby=$it,$it,$it,$it...) from causing stack overflows
72+
if (orderByItSeen)
73+
{
74+
throw new ODataException(Error.Format(SRResources.OrderByDuplicateIt));
75+
}
76+
77+
querySoFar = ExpressionHelpers.OrderByIt(querySoFar, node.Direction, typeof(T), alreadyOrdered);
78+
alreadyOrdered = true;
79+
orderByItSeen = true;
80+
}
81+
}
82+
83+
return querySoFar as IOrderedQueryable;
84+
}
85+
86+
private static IQueryable AddOrderByQueryForProperty<T>(ODataQuery<T> query, ODataQuerySettings querySettings,
87+
OrderByClause orderbyClause, IQueryable querySoFar, OrderByDirection direction, bool alreadyOrdered)
88+
{
89+
//Context.UpdateQuerySettings(querySettings, query);
90+
91+
LambdaExpression orderByExpression =
92+
FilterBinder.Bind(query, orderbyClause, typeof(T), query.ServiceProvider);
93+
querySoFar = ExpressionHelpers.OrderBy(querySoFar, orderByExpression, direction, typeof(T),
94+
alreadyOrdered);
95+
return querySoFar;
96+
}
97+
}
98+
}

Community.Data.OData.Linq/OdataLinqExtensions.cs

Lines changed: 11 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,25 @@
1-
using Community.OData.Linq.Builder.Validators;
2-
using Community.OData.Linq.Common;
3-
using Community.OData.Linq.Properties;
4-
5-
namespace Community.OData.Linq
1+
namespace Community.OData.Linq
62
{
73
using System;
84
using System.Collections.Generic;
95
using System.ComponentModel.Design;
106
using System.Diagnostics.Contracts;
117
using System.Linq;
128
using System.Linq.Expressions;
13-
9+
1410
using Community.OData.Linq.Builder;
11+
using Community.OData.Linq.Builder.Validators;
1512
using Community.OData.Linq.OData;
1613
using Community.OData.Linq.OData.Query;
17-
using Community.OData.Linq.OData.Query.Expressions;
14+
using Community.OData.Linq.OData.Query.Expressions;
1815

1916
using Microsoft.Extensions.DependencyInjection;
2017
using Microsoft.OData;
2118
using Microsoft.OData.Edm;
2219
using Microsoft.OData.UriParser;
2320

2421
public static class ODataLinqExtensions
25-
{
26-
private static readonly FilterQueryValidator FilterValidator =
27-
new FilterQueryValidator(new DefaultQuerySettings {EnableFilter = true});
28-
29-
private static readonly OrderByQueryValidator OrderValidator =
30-
new OrderByQueryValidator(new DefaultQuerySettings { EnableOrderBy = true });
31-
22+
{
3223
/// <summary>
3324
/// The simplified options.
3425
/// </summary>
@@ -112,7 +103,8 @@ public static ODataQuery<T> Filter<T>(this ODataQuery<T> query, string filterTex
112103
filterClause = new FilterClause(filterExpression, filterClause.RangeVariable);
113104
Contract.Assert(filterClause != null);
114105

115-
FilterValidator.Validate(filterClause, settings.ValidationSettings, edmModel);
106+
var validator = new FilterQueryValidator(new DefaultQuerySettings { EnableFilter = true });
107+
validator.Validate(filterClause, settings.ValidationSettings, edmModel);
116108

117109
Expression filter = FilterBinder.Bind(query, filterClause, typeof(T), query.ServiceProvider);
118110
var result = ExpressionHelpers.Where(query, filter, typeof(T));
@@ -141,93 +133,13 @@ public static IOrderedQueryable<T> OrderBy<T>(this ODataQuery<T> query, string o
141133

142134
ICollection<OrderByNode> nodes = OrderByNode.CreateCollection(orderByClause);
143135

144-
OrderValidator.Validate(nodes, settings.ValidationSettings, edmModel);
136+
var validator = new OrderByQueryValidator(new DefaultQuerySettings { EnableOrderBy = true });
137+
validator.Validate(nodes, settings.ValidationSettings, edmModel);
145138

146-
IOrderedQueryable<T> result = (IOrderedQueryable<T>)OrderApplyToCore<T>(query, settings.QuerySettings, nodes, edmModel);
139+
IOrderedQueryable<T> result = (IOrderedQueryable<T>)OrderByBinder.OrderApplyToCore(query, settings.QuerySettings, nodes, edmModel);
147140

148141
return new ODataQueryOrdered<T>(result, query.ServiceProvider);
149-
}
150-
151-
private static IOrderedQueryable OrderApplyToCore<T>(ODataQuery<T> query, ODataQuerySettings querySettings, ICollection<OrderByNode> nodes, IEdmModel model)
152-
{
153-
bool alreadyOrdered = false;
154-
IQueryable querySoFar = query;
155-
156-
HashSet<object> propertiesSoFar = new HashSet<object>();
157-
HashSet<string> openPropertiesSoFar = new HashSet<string>();
158-
bool orderByItSeen = false;
159-
160-
foreach (OrderByNode node in nodes)
161-
{
162-
OrderByPropertyNode propertyNode = node as OrderByPropertyNode;
163-
OrderByOpenPropertyNode openPropertyNode = node as OrderByOpenPropertyNode;
164-
165-
if (propertyNode != null)
166-
{
167-
// Use autonomy class to achieve value equality for HasSet.
168-
var edmPropertyWithPath = new { propertyNode.Property, propertyNode.PropertyPath };
169-
OrderByDirection direction = propertyNode.Direction;
170-
171-
// This check prevents queries with duplicate properties (e.g. $orderby=Id,Id,Id,Id...) from causing stack overflows
172-
if (propertiesSoFar.Contains(edmPropertyWithPath))
173-
{
174-
throw new ODataException(Error.Format(SRResources.OrderByDuplicateProperty, edmPropertyWithPath.PropertyPath));
175-
}
176-
177-
propertiesSoFar.Add(edmPropertyWithPath);
178-
179-
if (propertyNode.OrderByClause != null)
180-
{
181-
querySoFar = AddOrderByQueryForProperty(query, querySettings, propertyNode.OrderByClause, querySoFar, direction, alreadyOrdered);
182-
}
183-
else
184-
{
185-
querySoFar = ExpressionHelpers.OrderByProperty(querySoFar, model, edmPropertyWithPath.Property, direction, typeof(T), alreadyOrdered);
186-
}
187-
188-
alreadyOrdered = true;
189-
}
190-
else if (openPropertyNode != null)
191-
{
192-
// This check prevents queries with duplicate properties (e.g. $orderby=Id,Id,Id,Id...) from causing stack overflows
193-
if (openPropertiesSoFar.Contains(openPropertyNode.PropertyName))
194-
{
195-
throw new ODataException(Error.Format(SRResources.OrderByDuplicateProperty, openPropertyNode.PropertyPath));
196-
}
197-
198-
openPropertiesSoFar.Add(openPropertyNode.PropertyName);
199-
Contract.Assert(openPropertyNode.OrderByClause != null);
200-
querySoFar = AddOrderByQueryForProperty(query, querySettings, openPropertyNode.OrderByClause, querySoFar, openPropertyNode.Direction, alreadyOrdered);
201-
alreadyOrdered = true;
202-
}
203-
else
204-
{
205-
// This check prevents queries with duplicate nodes (e.g. $orderby=$it,$it,$it,$it...) from causing stack overflows
206-
if (orderByItSeen)
207-
{
208-
throw new ODataException(Error.Format(SRResources.OrderByDuplicateIt));
209-
}
210-
211-
querySoFar = ExpressionHelpers.OrderByIt(querySoFar, node.Direction, typeof(T), alreadyOrdered);
212-
alreadyOrdered = true;
213-
orderByItSeen = true;
214-
}
215-
}
216-
217-
return querySoFar as IOrderedQueryable;
218-
}
219-
220-
private static IQueryable AddOrderByQueryForProperty<T>(ODataQuery<T> query, ODataQuerySettings querySettings,
221-
OrderByClause orderbyClause, IQueryable querySoFar, OrderByDirection direction, bool alreadyOrdered)
222-
{
223-
//Context.UpdateQuerySettings(querySettings, query);
224-
225-
LambdaExpression orderByExpression =
226-
FilterBinder.Bind(query, orderbyClause, typeof(T), query.ServiceProvider);
227-
querySoFar = ExpressionHelpers.OrderBy(querySoFar, orderByExpression, direction, typeof(T),
228-
alreadyOrdered);
229-
return querySoFar;
230-
}
142+
}
231143

232144
private static OrderByClause TranslateParameterAlias(OrderByClause orderBy, ODataQueryOptionParser queryOptionParser)
233145
{

0 commit comments

Comments
 (0)