Skip to content

Commit 4f38f1e

Browse files
authored
Remove string comparison support (#1099)
1 parent 52f24f2 commit 4f38f1e

15 files changed

+51
-187
lines changed

docs/mdsource/query-usage.source.md

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -246,25 +246,6 @@ Or:
246246
```
247247

248248

249-
#### Case Sensitivity
250-
251-
All string comparisons are, by default, done using no [StringComparison](https://msdn.microsoft.com/en-us/library/system.stringcomparison.aspx). A custom StringComparison can be used via the `case` attribute.
252-
253-
```graphql
254-
{
255-
entities
256-
(where: {
257-
path: "Property",
258-
comparison: "endsWith",
259-
value: "the value",
260-
case: "Ordinal"})
261-
{
262-
property
263-
}
264-
}
265-
```
266-
267-
268249
#### Null
269250

270251
Null can be expressed by omitting the `value`:

docs/query-usage.md

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -253,25 +253,6 @@ Or:
253253
```
254254

255255

256-
#### Case Sensitivity
257-
258-
All string comparisons are, by default, done using no [StringComparison](https://msdn.microsoft.com/en-us/library/system.stringcomparison.aspx). A custom StringComparison can be used via the `case` attribute.
259-
260-
```graphql
261-
{
262-
entities
263-
(where: {
264-
path: "Property",
265-
comparison: "endsWith",
266-
value: "the value",
267-
case: "Ordinal"})
268-
{
269-
property
270-
}
271-
}
272-
```
273-
274-
275256
#### Null
276257

277258
Null can be expressed by omitting the `value`:

src/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<Project>
33
<PropertyGroup>
44
<NoWarn>CS1591;NU5104;CS1573;CS9107;NU1608;NU1109</NoWarn>
5-
<Version>30.0.0</Version>
5+
<Version>31.0.0</Version>
66
<LangVersion>preview</LangVersion>
77
<AssemblyVersion>1.0.0</AssemblyVersion>
88
<PackageTags>EntityFrameworkCore, EntityFramework, GraphQL</PackageTags>

src/GraphQL.EntityFramework.sln

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1010
Directory.Packages.props = Directory.Packages.props
1111
mdsnippets.json = mdsnippets.json
1212
global.json = global.json
13+
..\readme.source.md = ..\readme.source.md
1314
EndProjectSection
1415
EndProject
1516
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GraphQL.EntityFramework", "GraphQL.EntityFramework\GraphQL.EntityFramework.csproj", "{92E64F4E-6A8E-43C2-9C8D-694E0327BEF0}"

src/GraphQL.EntityFramework/EfGraphQLConventions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ static TDbContext DbContextFromProvider<TDbContext>(IServiceProvider provider, I
8484

8585
static void RegisterScalarsAndArgs(IServiceCollection services)
8686
{
87-
services.AddSingleton<EnumerationGraphType<StringComparison>>();
8887
services.AddSingleton<EnumerationGraphType<DayOfWeek>>();
8988
services.AddSingleton<WhereExpressionGraph>();
9089
services.AddSingleton<OrderByGraph>();

src/GraphQL.EntityFramework/Where/ExpressionBuilder.cs

Lines changed: 39 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ static Expression MakePredicateBody(IReadOnlyCollection<WhereExpression> wheres)
4040
else
4141
{
4242
// Get the predicate body for the single expression
43-
nextExpression = MakePredicateBody(where.Path, where.Comparison, where.Value, where.Negate, where.Case);
43+
nextExpression = MakePredicateBody(where.Path, where.Comparison, where.Value, where.Negate);
4444
}
4545

4646
// If this is the first where processed
@@ -65,29 +65,29 @@ static Expression MakePredicateBody(IReadOnlyCollection<WhereExpression> wheres)
6565
/// <summary>
6666
/// Create a single predicate for the single set of supplied conditional arguments
6767
/// </summary>
68-
public static Expression<Func<T, bool>> BuildPredicate(string path, Comparison comparison, string?[]? values, bool negate = false, StringComparison? stringComparison = null)
68+
public static Expression<Func<T, bool>> BuildPredicate(string path, Comparison comparison, string?[]? values, bool negate = false)
6969
{
70-
var expressionBody = MakePredicateBody(path, comparison, values, negate, stringComparison);
70+
var expressionBody = MakePredicateBody(path, comparison, values, negate);
7171
var param = PropertyCache<T>.SourceParameter;
7272

7373
return Expression.Lambda<Func<T, bool>>(expressionBody, param);
7474
}
7575

76-
static Expression MakePredicateBody(string path, Comparison comparison, string?[]? values, bool negate, StringComparison? stringComparison)
76+
static Expression MakePredicateBody(string path, Comparison comparison, string?[]? values, bool negate)
7777
{
7878
Expression expressionBody;
7979

8080
// If path includes list property access
8181
if (HasListPropertyInPath(path))
8282
{
8383
// Handle a list path
84-
expressionBody = ProcessList(path, comparison, values!, stringComparison);
84+
expressionBody = ProcessList(path, comparison, values!);
8585
}
8686
// Otherwise linear property access
8787
else
8888
{
8989
// Just get expression
90-
expressionBody = GetExpression(path, comparison, values, stringComparison);
90+
expressionBody = GetExpression(path, comparison, values);
9191
}
9292

9393
// If the expression should be negated
@@ -99,7 +99,7 @@ static Expression MakePredicateBody(string path, Comparison comparison, string?[
9999
return expressionBody;
100100
}
101101

102-
static Expression ProcessList(string path, Comparison comparison, string?[]? values, StringComparison? stringComparison)
102+
static Expression ProcessList(string path, Comparison comparison, string?[]? values)
103103
{
104104
// Get the path pertaining to individual list items
105105
var listPath = ListPropertyRegex().Match(path).Groups[1].Value;
@@ -118,7 +118,7 @@ static Expression ProcessList(string path, Comparison comparison, string?[]? val
118118
var buildPredicate = genericType
119119
.GetMethods(BindingFlags.Public | BindingFlags.Static)
120120
.SingleOrDefault(_ => _.Name == "BuildPredicate" &&
121-
_.GetParameters().Length == 5);
121+
_.GetParameters().Length == 4);
122122
if (buildPredicate == null)
123123
{
124124
throw new($"Could not find BuildPredicate method on {genericType.FullName}");
@@ -131,8 +131,7 @@ static Expression ProcessList(string path, Comparison comparison, string?[]? val
131131
listPath,
132132
comparison,
133133
values!,
134-
false,
135-
stringComparison!
134+
false
136135
])!;
137136

138137
// Generate a method info for the Any Enumerable Static Method
@@ -146,7 +145,7 @@ static Expression ProcessList(string path, Comparison comparison, string?[]? val
146145
return Expression.Call(anyInfo, property.Left, subPredicate);
147146
}
148147

149-
static Expression GetExpression(string path, Comparison comparison, string?[]? values, StringComparison? stringComparison)
148+
static Expression GetExpression(string path, Comparison comparison, string?[]? values)
150149
{
151150
var property = PropertyCache<T>.GetProperty(path);
152151
Expression expressionBody;
@@ -156,18 +155,18 @@ static Expression GetExpression(string path, Comparison comparison, string?[]? v
156155
switch (comparison)
157156
{
158157
case Comparison.NotIn:
159-
WhereValidator.ValidateString(comparison, stringComparison);
160-
expressionBody = NegateExpression(MakeStringListInComparison(values!, property, stringComparison)); // Ensure expression is negated
158+
WhereValidator.ValidateString(comparison);
159+
expressionBody = NegateExpression(MakeStringListInComparison(values!, property)); // Ensure expression is negated
161160
break;
162161
case Comparison.In:
163-
WhereValidator.ValidateString(comparison, stringComparison);
164-
expressionBody = MakeStringListInComparison(values!, property, stringComparison);
162+
WhereValidator.ValidateString(comparison);
163+
expressionBody = MakeStringListInComparison(values!, property);
165164
break;
166165

167166
default:
168-
WhereValidator.ValidateSingleString(comparison, stringComparison);
167+
WhereValidator.ValidateSingleString(comparison);
169168
var value = values?.Single();
170-
expressionBody = MakeSingleStringComparison(comparison, value, property, stringComparison);
169+
expressionBody = MakeSingleStringComparison(comparison, value, property);
171170
break;
172171
}
173172
}
@@ -176,16 +175,16 @@ static Expression GetExpression(string path, Comparison comparison, string?[]? v
176175
switch (comparison)
177176
{
178177
case Comparison.NotIn:
179-
WhereValidator.ValidateObject(property.PropertyType, comparison, stringComparison);
178+
WhereValidator.ValidateObject(property.PropertyType, comparison);
180179
expressionBody = NegateExpression(MakeObjectListInComparision(values!, property));
181180
break;
182181
case Comparison.In:
183-
WhereValidator.ValidateObject(property.PropertyType, comparison, stringComparison);
182+
WhereValidator.ValidateObject(property.PropertyType, comparison);
184183
expressionBody = MakeObjectListInComparision(values!, property);
185184
break;
186185

187186
default:
188-
WhereValidator.ValidateSingleObject(property.PropertyType, comparison, null);
187+
WhereValidator.ValidateSingleObject(property.PropertyType, comparison);
189188
var value = values?.Single();
190189
var valueObject = TypeConverter.ConvertStringToType(value, property.PropertyType);
191190
expressionBody = MakeSingleObjectComparison(comparison, valueObject, property);
@@ -211,20 +210,9 @@ static Expression MakeObjectListInComparision(string[] values, Property<T> prope
211210
return Expression.Call(constant, property.ListContains, property.Left);
212211
}
213212

214-
static Expression MakeStringListInComparison(string[] values, Property<T> property, StringComparison? comparison)
213+
static Expression MakeStringListInComparison(string[] values, Property<T> property)
215214
{
216-
MethodCallExpression equalsBody;
217-
218-
if (comparison is null)
219-
{
220-
// Do basic string compare
221-
equalsBody = Expression.Call(null, ReflectionCache.StringEqual, ExpressionCache.StringParam, property.Left);
222-
}
223-
else
224-
{
225-
// String comparison with comparison type value
226-
equalsBody = Expression.Call(null, ReflectionCache.StringEqualComparison, ExpressionCache.StringParam, property.Left, Expression.Constant(comparison));
227-
}
215+
var equalsBody = Expression.Call(null, ReflectionCache.StringEqual, ExpressionCache.StringParam, property.Left);
228216

229217
// Make lambda for comparing each string value against property value
230218
var itemEvaluate = Expression.Lambda<Func<string, bool>>(equalsBody, ExpressionCache.StringParam);
@@ -233,55 +221,31 @@ static Expression MakeStringListInComparison(string[] values, Property<T> proper
233221
return Expression.Call(null, ReflectionCache.StringAny, Expression.Constant(values), itemEvaluate);
234222
}
235223

236-
static Expression MakeSingleStringComparison(Comparison comparison, string? value, Property<T> property, StringComparison? stringComparison)
224+
static Expression MakeSingleStringComparison(Comparison comparison, string? value, Property<T> property)
237225
{
238226
var left = property.Left;
239227

240228
var valueConstant = Expression.Constant(value, typeof(string));
241229
var nullCheck = Expression.NotEqual(left, ExpressionCache.Null);
242230

243-
if (stringComparison is null)
231+
switch (comparison)
244232
{
245-
switch (comparison)
246-
{
247-
case Comparison.Equal:
248-
return Expression.Call(ReflectionCache.StringEqual, left, valueConstant);
249-
case Comparison.NotEqual:
250-
return Expression.Not(Expression.Call(ReflectionCache.StringEqual, left, valueConstant));
251-
case Comparison.Like:
252-
return Expression.Call(null, ReflectionCache.StringLike, ExpressionCache.EfFunction, left, valueConstant);
253-
case Comparison.StartsWith:
254-
var startsWithExpression = Expression.Call(left, ReflectionCache.StringStartsWith, valueConstant);
255-
return Expression.AndAlso(nullCheck, startsWithExpression);
256-
case Comparison.EndsWith:
257-
var endsWithExpression = Expression.Call(left, ReflectionCache.StringEndsWith, valueConstant);
258-
return Expression.AndAlso(nullCheck, endsWithExpression);
259-
case Comparison.Contains:
260-
var indexOfExpression = Expression.Call(left, ReflectionCache.StringIndexOf, valueConstant);
261-
var notEqualExpression = Expression.NotEqual(indexOfExpression, ExpressionCache.NegativeOne);
262-
return Expression.AndAlso(nullCheck, notEqualExpression);
263-
}
264-
}
265-
else
266-
{
267-
var comparisonConstant = Expression.Constant(stringComparison, typeof(StringComparison));
268-
switch (comparison)
269-
{
270-
case Comparison.Equal:
271-
return Expression.Call(ReflectionCache.StringEqualComparison, left, valueConstant, comparisonConstant);
272-
case Comparison.NotEqual:
273-
return Expression.Not(Expression.Call(ReflectionCache.StringEqualComparison, left, valueConstant, comparisonConstant));
274-
case Comparison.StartsWith:
275-
var startsWithExpression = Expression.Call(left, ReflectionCache.StringStartsWithComparison, valueConstant, comparisonConstant);
276-
return Expression.AndAlso(nullCheck, startsWithExpression);
277-
case Comparison.EndsWith:
278-
var endsWithExpression = Expression.Call(left, ReflectionCache.StringEndsWithComparison, valueConstant, comparisonConstant);
279-
return Expression.AndAlso(nullCheck, endsWithExpression);
280-
case Comparison.Contains:
281-
var indexOfExpression = Expression.Call(left, ReflectionCache.StringIndexOfComparison, valueConstant, comparisonConstant);
282-
var notEqualExpression = Expression.NotEqual(indexOfExpression, ExpressionCache.NegativeOne);
283-
return Expression.AndAlso(nullCheck, notEqualExpression);
284-
}
233+
case Comparison.Equal:
234+
return Expression.Call(ReflectionCache.StringEqual, left, valueConstant);
235+
case Comparison.NotEqual:
236+
return Expression.Not(Expression.Call(ReflectionCache.StringEqual, left, valueConstant));
237+
case Comparison.Like:
238+
return Expression.Call(null, ReflectionCache.StringLike, ExpressionCache.EfFunction, left, valueConstant);
239+
case Comparison.StartsWith:
240+
var startsWithExpression = Expression.Call(left, ReflectionCache.StringStartsWith, valueConstant);
241+
return Expression.AndAlso(nullCheck, startsWithExpression);
242+
case Comparison.EndsWith:
243+
var endsWithExpression = Expression.Call(left, ReflectionCache.StringEndsWith, valueConstant);
244+
return Expression.AndAlso(nullCheck, endsWithExpression);
245+
case Comparison.Contains:
246+
var indexOfExpression = Expression.Call(left, ReflectionCache.StringIndexOf, valueConstant);
247+
var notEqualExpression = Expression.NotEqual(indexOfExpression, ExpressionCache.NegativeOne);
248+
return Expression.AndAlso(nullCheck, notEqualExpression);
285249
}
286250

287251
throw new($"Invalid comparison operator '{comparison}'.");

src/GraphQL.EntityFramework/Where/Graphs/StringComparisonGraph.cs

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/GraphQL.EntityFramework/Where/Graphs/WhereExpression.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ public class WhereExpression
44
{
55
public string Path { get; set; } = string.Empty;
66
public Comparison Comparison { get; set; } = Comparison.Equal;
7-
public StringComparison? Case { get; set; }
87
public string[]? Value { get; set; }
98
public bool Negate { get; set; }
109
public Connector Connector { get; set; } = Connector.And;

src/GraphQL.EntityFramework/Where/Graphs/WhereExpressionGraph.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ public WhereExpressionGraph()
99
Field(_ => _.Path, true);
1010
Field<ComparisonGraph>("comparison");
1111
Field(_ => _.Negate, true);
12-
Field<EnumerationGraphType<StringComparison>>("case");
1312
Field(_ => _.Value, true);
1413
Field<ConnectorGraph>("connector");
1514
Field<ListGraphType<WhereExpressionGraph>>("GroupedExpressions");

src/GraphQL.EntityFramework/Where/ReflectionCache.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,9 @@
2222
static MethodInfo dateTimeOffsetListContains;
2323
static MethodInfo dateTimeOffsetNullableListContains;
2424
public static MethodInfo StringLike = typeof(DbFunctionsExtensions).GetMethod("Like", [typeof(DbFunctions), typeof(string), typeof(string)])!;
25-
public static MethodInfo StringEqualComparison = typeof(string).GetMethod("Equals", [typeof(string), typeof(string), typeof(StringComparison)])!;
2625
public static MethodInfo StringEqual = typeof(string).GetMethod("Equals", [typeof(string), typeof(string)])!;
27-
public static MethodInfo StringStartsWithComparison = typeof(string).GetMethod("StartsWith", [typeof(string), typeof(StringComparison)])!;
2826
public static MethodInfo StringStartsWith = typeof(string).GetMethod("StartsWith", [typeof(string)])!;
29-
public static MethodInfo StringIndexOfComparison = typeof(string).GetMethod("IndexOf", [typeof(string), typeof(StringComparison)])!;
3027
public static MethodInfo StringIndexOf = typeof(string).GetMethod("IndexOf", [typeof(string)])!;
31-
public static MethodInfo StringEndsWithComparison = typeof(string).GetMethod("EndsWith", [typeof(string), typeof(StringComparison)])!;
3228
public static MethodInfo StringEndsWith = typeof(string).GetMethod("EndsWith", [typeof(string)])!;
3329

3430
static ReflectionCache()

0 commit comments

Comments
 (0)