Skip to content

Commit 902dd90

Browse files
Refactor DataSourceExpressionBuilder (#402)
1 parent 168b598 commit 902dd90

10 files changed

Lines changed: 154 additions & 136 deletions

net/DevExtreme.AspNet.Data.Tests/Bug240Tests.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ namespace DevExtreme.AspNet.Data.Tests {
77

88
public class Bug240Tests {
99

10-
static DataSourceLoadOptionsBase CreateFullStuffedLoadOptions() {
10+
static DataSourceLoadOptionsBase CreateFullStuffedLoadOptions(bool guardNulls) {
1111
var selector = "Item1.Year";
1212

1313
return new SampleLoadOptions {
14+
GuardNulls = guardNulls,
1415
Filter = new[] { selector, "123" },
1516
Sort = new[] {
1617
new SortingInfo { Selector = selector }
@@ -43,7 +44,7 @@ static string FormatExpectedSelectorExpr(bool convertToNullable, bool guardNulls
4344

4445
[Fact]
4546
public void BuildLoadExpr_NoGuardNulls() {
46-
var expr = Compat.CreateDataSourceExpressionBuilder<Tuple<DateTime?>>(CreateFullStuffedLoadOptions(), false).BuildLoadExpr();
47+
var expr = Compat.CreateDataSourceExpressionBuilder<Tuple<DateTime?>>(CreateFullStuffedLoadOptions(false)).BuildLoadExpr();
4748

4849
Assert.Equal(
4950
"data"
@@ -61,7 +62,7 @@ public void BuildLoadExpr_NoGuardNulls() {
6162

6263
[Fact]
6364
public void BuildLoadExpr_WithGuardNulls() {
64-
var expr = Compat.CreateDataSourceExpressionBuilder<Tuple<DateTime?>>(CreateFullStuffedLoadOptions(), true).BuildLoadExpr();
65+
var expr = Compat.CreateDataSourceExpressionBuilder<Tuple<DateTime?>>(CreateFullStuffedLoadOptions(true)).BuildLoadExpr();
6566

6667
Assert.Equal(
6768
"data"
@@ -77,7 +78,7 @@ public void BuildLoadExpr_WithGuardNulls() {
7778

7879
[Fact]
7980
public void BuildLoadGroupsExpr_NoGuardNulls() {
80-
var expr = Compat.CreateDataSourceExpressionBuilder<Tuple<DateTime?>>(CreateFullStuffedLoadOptions(), false).BuildLoadGroupsExpr();
81+
var expr = Compat.CreateDataSourceExpressionBuilder<Tuple<DateTime?>>(CreateFullStuffedLoadOptions(false)).BuildLoadGroupsExpr();
8182

8283
Assert.Equal(
8384
// Only selectors that land in .Select() use conversion to Nullable
@@ -97,7 +98,7 @@ public void BuildLoadGroupsExpr_NoGuardNulls() {
9798

9899
[Fact]
99100
public void BuildLoadGroupsExpr_WithGuardNulls() {
100-
var expr = Compat.CreateDataSourceExpressionBuilder<Tuple<DateTime?>>(CreateFullStuffedLoadOptions(), true).BuildLoadGroupsExpr();
101+
var expr = Compat.CreateDataSourceExpressionBuilder<Tuple<DateTime?>>(CreateFullStuffedLoadOptions(true)).BuildLoadGroupsExpr();
101102

102103
Assert.Equal(
103104
// All selectors are guarded and use conversion to Nullable

net/DevExtreme.AspNet.Data.Tests/Compat.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Linq;
3+
using System.Linq.Expressions;
34
using System.Text;
45

56
namespace DevExtreme.AspNet.Data.Tests {
@@ -16,14 +17,19 @@ public static string ExpectedConvert(object subj, string type) {
1617
return text.Append(")").ToString();
1718
}
1819

19-
public static DataSourceExpressionBuilder<T> CreateDataSourceExpressionBuilder<T>(DataSourceLoadOptionsBase options, bool guardNulls = false) {
20+
public static DataSourceExpressionBuilder<T> CreateDataSourceExpressionBuilder<T>(DataSourceLoadOptionsBase options) {
21+
var source = new EnumerableQuery<T>(Expression.Parameter(typeof(IQueryable<T>), "data"));
22+
return CreateDataSourceExpressionBuilder(source, options);
23+
}
24+
25+
public static DataSourceExpressionBuilder<T> CreateDataSourceExpressionBuilder<T>(IQueryable<T> source, DataSourceLoadOptionsBase options) {
2026
return new DataSourceExpressionBuilder<T>(
27+
source.Expression,
2128
new DataSourceLoadContext(
2229
options,
23-
new QueryProviderInfo(new T[0].AsQueryable().Provider),
30+
new QueryProviderInfo(source.Provider),
2431
typeof(T)
25-
),
26-
guardNulls
32+
)
2733
);
2834
}
2935
}

net/DevExtreme.AspNet.Data.Tests/DataSourceExpressionBuilderTests.cs

Lines changed: 54 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ public class DataSourceExpressionBuilderTests {
1212
public void Build_SkipTake() {
1313
var builder = Compat.CreateDataSourceExpressionBuilder<int>(new SampleLoadOptions {
1414
Skip = 111,
15-
Take = 222
15+
Take = 222,
16+
GuardNulls = false
1617
});
1718

1819
var expr = builder.BuildLoadExpr();
@@ -23,7 +24,8 @@ public void Build_SkipTake() {
2324
[Fact]
2425
public void Build_Filter() {
2526
var builder = Compat.CreateDataSourceExpressionBuilder<int>(new SampleLoadOptions {
26-
Filter = new object[] { "this", ">", 123 }
27+
Filter = new object[] { "this", ">", 123 },
28+
GuardNulls = false
2729
});
2830

2931
var expr = builder.BuildLoadExpr();
@@ -36,7 +38,8 @@ public void Build_FilterAsEmptyList() {
3638
// To mitigate cases like https://devexpress.com/issue=T483154
3739

3840
var builder = Compat.CreateDataSourceExpressionBuilder<int>(new SampleLoadOptions {
39-
Filter = new object[0]
41+
Filter = new object[0],
42+
GuardNulls = false
4043
});
4144

4245
Assert.DoesNotContain(".Where", builder.BuildLoadExpr().ToString());
@@ -51,6 +54,7 @@ public void Build_CountQuery() {
5154
Sort = new[] {
5255
new SortingInfo { Selector = "this" }
5356
},
57+
GuardNulls = false
5458
});
5559

5660
var expr = builder.BuildCountExpr();
@@ -74,7 +78,8 @@ public void Build_Sorting() {
7478
Selector = "Item2",
7579
Desc=true
7680
}
77-
}
81+
},
82+
GuardNulls = false
7883
});
7984

8085
var expr = builder.BuildLoadExpr();
@@ -91,18 +96,19 @@ public void GroupingAddedToSorting() {
9196
Group = new[] {
9297
new GroupingInfo { Selector = "Item1" },
9398
new GroupingInfo { Selector = "Item2", Desc = true } // this must win
94-
}
99+
},
100+
GuardNulls = false
95101
};
96102

97-
var builder = Compat.CreateDataSourceExpressionBuilder<Tuple<int, int, int>>(loadOptions);
103+
string BuildLoadExpr() => Compat.CreateDataSourceExpressionBuilder<Tuple<int, int, int>>(loadOptions).BuildLoadExpr().ToString();
98104

99105
Assert.Equal(
100106
"data.OrderBy(obj => obj.Item1).ThenByDescending(obj => obj.Item2).ThenBy(obj => obj.Item3)",
101-
builder.BuildLoadExpr().ToString()
107+
BuildLoadExpr()
102108
);
103109

104110
loadOptions.Sort = null;
105-
Assert.Contains("OrderBy", builder.BuildLoadExpr().ToString());
111+
Assert.Contains("OrderBy", BuildLoadExpr());
106112
}
107113

108114
[Fact]
@@ -111,28 +117,15 @@ public void MultiIntervalGroupsSortedOnce() {
111117
Group = new[] {
112118
new GroupingInfo { Selector = "this", GroupInterval = "a" },
113119
new GroupingInfo { Selector = "this", GroupInterval = "b" }
114-
}
120+
},
121+
GuardNulls = false
115122
});
116123

117124
Assert.Equal("data.OrderBy(obj => obj)", builder.BuildLoadExpr().ToString());
118125
}
119126

120127
[Fact]
121128
public void GuardNulls() {
122-
var builder = Compat.CreateDataSourceExpressionBuilder<Tuple<int?, string, DateTime?>>(new SampleLoadOptions {
123-
Filter = new[] {
124-
new[] { "Item1", ">", "0" },
125-
new[] { "Item2", "contains", "z" },
126-
new[] { "Item2.Length", ">", "1" },
127-
new[] { "Item3.Year", ">", "0" }
128-
},
129-
Sort = new[] {
130-
new SortingInfo { Selector = "Item1" },
131-
new SortingInfo { Selector = "Item2.Length" },
132-
new SortingInfo { Selector = "Item3.Year" },
133-
}
134-
}, true);
135-
136129
var data = new[] {
137130
// filtered out
138131
null,
@@ -146,29 +139,45 @@ public void GuardNulls() {
146139
Tuple.Create<int?, string, DateTime?>(1, "zz", new DateTime(2000, 1, 1))
147140
}.AsQueryable();
148141

149-
var expr = builder.BuildLoadExpr(data.Expression);
142+
var builder = Compat.CreateDataSourceExpressionBuilder(data, new SampleLoadOptions {
143+
Filter = new[] {
144+
new[] { "Item1", ">", "0" },
145+
new[] { "Item2", "contains", "z" },
146+
new[] { "Item2.Length", ">", "1" },
147+
new[] { "Item3.Year", ">", "0" }
148+
},
149+
Sort = new[] {
150+
new SortingInfo { Selector = "Item1" },
151+
new SortingInfo { Selector = "Item2.Length" },
152+
new SortingInfo { Selector = "Item3.Year" },
153+
},
154+
GuardNulls = true
155+
});
156+
157+
var expr = builder.BuildLoadExpr();
150158
var result = data.Provider.CreateQuery<object>(expr).ToArray();
151159
Assert.Equal(2, result.Length);
152160
}
153161

154162
[Fact]
155163
public void DefaultSort() {
156164
var options = new SampleLoadOptions {
157-
DefaultSort = "Item1"
165+
DefaultSort = "Item1",
166+
GuardNulls = false
158167
};
159168

160-
var builder = Compat.CreateDataSourceExpressionBuilder<Tuple<int, int>>(options, false);
169+
string BuildLoadExpr() => Compat.CreateDataSourceExpressionBuilder<Tuple<int, int>>(options).BuildLoadExpr(false).ToString();
161170

162-
Assert.Equal("data.OrderBy(obj => obj.Item1)", builder.BuildLoadExpr(false).ToString());
171+
Assert.Equal("data.OrderBy(obj => obj.Item1)", BuildLoadExpr());
163172

164173
options.Sort = new[] {
165174
new SortingInfo { Selector = "Item2" }
166175
};
167176

168-
Assert.Equal("data.OrderBy(obj => obj.Item2).ThenBy(obj => obj.Item1)", builder.BuildLoadExpr(false).ToString());
177+
Assert.Equal("data.OrderBy(obj => obj.Item2).ThenBy(obj => obj.Item1)", BuildLoadExpr());
169178

170179
options.Sort[0].Selector = "Item1";
171-
Assert.Equal("data.OrderBy(obj => obj.Item1)", builder.BuildLoadExpr(false).ToString());
180+
Assert.Equal("data.OrderBy(obj => obj.Item1)", BuildLoadExpr());
172181
}
173182

174183
[Fact]
@@ -180,10 +189,11 @@ public void NoUnnecessaryOrderingForRemoteGroups() {
180189
},
181190
Sort = new[] {
182191
new SortingInfo { Selector = "Item2" }
183-
}
192+
},
193+
GuardNulls = false
184194
};
185195

186-
var builder = Compat.CreateDataSourceExpressionBuilder<Tuple<int, int>>(options, false);
196+
var builder = Compat.CreateDataSourceExpressionBuilder<Tuple<int, int>>(options);
187197
var expr = builder.BuildLoadGroupsExpr().ToString();
188198

189199
Assert.StartsWith("data.GroupBy", expr);
@@ -192,10 +202,11 @@ public void NoUnnecessaryOrderingForRemoteGroups() {
192202
[Fact]
193203
public void AlwaysOrderDataByPrimaryKey() {
194204
var options = new SampleLoadOptions {
195-
PrimaryKey = new[] { "Item2", "Item1" }
205+
PrimaryKey = new[] { "Item2", "Item1" },
206+
GuardNulls = false
196207
};
197208

198-
var builder = Compat.CreateDataSourceExpressionBuilder<Tuple<int, int>>(options, false);
209+
var builder = Compat.CreateDataSourceExpressionBuilder<Tuple<int, int>>(options);
199210

200211
Assert.Equal(
201212
"data.OrderBy(obj => obj.Item2).ThenBy(obj => obj.Item1)",
@@ -208,11 +219,12 @@ public void DefaultSortAndPrimaryKey() {
208219
var options = new SampleLoadOptions {
209220
PrimaryKey = new[] { "Item1" },
210221
DefaultSort = "Item1",
211-
Sort = new[] { new SortingInfo { Selector = "Item1" } }
222+
Sort = new[] { new SortingInfo { Selector = "Item1" } },
223+
GuardNulls = false
212224
};
213225

214226
{
215-
var builder = Compat.CreateDataSourceExpressionBuilder<Tuple<int, int, int>>(options, false);
227+
var builder = Compat.CreateDataSourceExpressionBuilder<Tuple<int, int, int>>(options);
216228

217229
Assert.Equal(
218230
"data.OrderBy(obj => obj.Item1)",
@@ -224,7 +236,7 @@ public void DefaultSortAndPrimaryKey() {
224236
options.Sort[0].Selector = "Item3";
225237

226238
{
227-
var builder = Compat.CreateDataSourceExpressionBuilder<Tuple<int, int, int>>(options, false);
239+
var builder = Compat.CreateDataSourceExpressionBuilder<Tuple<int, int, int>>(options);
228240

229241
Assert.Equal(
230242
"data.OrderBy(obj => obj.Item3).ThenBy(obj => obj.Item2).ThenBy(obj => obj.Item1)",
@@ -241,10 +253,11 @@ public void PR202() {
241253
DefaultSort = "item1",
242254
Sort = new[] {
243255
new SortingInfo { Selector = "ITEM1" }
244-
}
256+
},
257+
GuardNulls = false
245258
};
246259

247-
var builder = Compat.CreateDataSourceExpressionBuilder<Tuple<int>>(options, false);
260+
var builder = Compat.CreateDataSourceExpressionBuilder<Tuple<int>>(options);
248261

249262
Assert.Equal(
250263
"data.OrderBy(obj => obj.Item1)",
@@ -256,12 +269,13 @@ public void PR202() {
256269
public void RemoteSelectFalse() {
257270
var options = new SampleLoadOptions {
258271
Select = new[] { "abc" },
259-
RemoteSelect = false
272+
RemoteSelect = false,
273+
GuardNulls = false
260274
};
261275

262276
Assert.Equal(
263277
"data",
264-
Compat.CreateDataSourceExpressionBuilder<object>(options, false).BuildLoadExpr().ToString()
278+
Compat.CreateDataSourceExpressionBuilder<object>(options).BuildLoadExpr().ToString()
265279
);
266280
}
267281
}
Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,10 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
42
using System.Linq.Expressions;
5-
using System.Text;
63

74
namespace DevExtreme.AspNet.Data.Tests {
85

96
static class Extensions {
10-
11-
public static Expression BuildLoadExpr<T>(this DataSourceExpressionBuilder<T> builder, bool paginate = true) {
12-
return builder.BuildLoadExpr(CreateSourceExpr<T>(), paginate);
13-
}
14-
15-
public static Expression BuildCountExpr<T>(this DataSourceExpressionBuilder<T> builder) {
16-
return builder.BuildCountExpr(CreateSourceExpr<T>());
17-
}
18-
19-
public static Expression BuildLoadGroupsExpr<T>(this DataSourceExpressionBuilder<T> builder) {
20-
return builder.BuildLoadGroupsExpr(CreateSourceExpr<T>(), false);
21-
}
22-
23-
static Expression CreateSourceExpr<T>() {
24-
return Expression.Parameter(typeof(IQueryable<T>), "data");
25-
}
26-
7+
public static Expression BuildLoadExpr<T>(this DataSourceExpressionBuilder<T> builder) => builder.BuildLoadExpr(true);
278
}
289

2910
}

net/DevExtreme.AspNet.Data.Tests/PaginateViaPrimaryKeyTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public void SingleKey() {
1414
.ToArray();
1515

1616
var loadOptions = new SampleLoadOptions {
17-
SuppressGuardNulls = true,
17+
GuardNulls = false,
1818

1919
PrimaryKey = new[] { "ID" },
2020
PaginateViaPrimaryKey = true,
@@ -56,7 +56,7 @@ public void MultiKey() {
5656
.ToArray();
5757

5858
var loadOptions = new SampleLoadOptions {
59-
SuppressGuardNulls = true,
59+
GuardNulls = false,
6060

6161
PrimaryKey = new[] { "K1", "K2" },
6262
PaginateViaPrimaryKey = true,
@@ -80,7 +80,7 @@ public void ActiveForFirstPage() {
8080
};
8181

8282
var loadOptions = new SampleLoadOptions {
83-
SuppressGuardNulls = true,
83+
GuardNulls = false,
8484
PrimaryKey = new[] { "ID" },
8585
PaginateViaPrimaryKey = true,
8686

@@ -96,7 +96,7 @@ public void ActiveForFirstPage() {
9696
[Fact]
9797
public void DisabledWithoutTake() {
9898
var loadOptions = new SampleLoadOptions {
99-
SuppressGuardNulls = true,
99+
GuardNulls = false,
100100
PaginateViaPrimaryKey = true
101101
};
102102

net/DevExtreme.AspNet.Data.Tests/RemoteGroupingTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ public void ExpandLinqSumType() {
422422
};
423423

424424
var loadOptions = new SampleLoadOptions {
425-
SuppressGuardNulls = true,
425+
GuardNulls = false,
426426
TotalSummary = new[] {
427427
nameof(sourceItem.SByte),
428428
nameof(sourceItem.Byte),

0 commit comments

Comments
 (0)