Skip to content

Commit 0fbeb5f

Browse files
ExpandLinqSumType option (#398)
1 parent f44330c commit 0fbeb5f

File tree

16 files changed

+357
-31
lines changed

16 files changed

+357
-31
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Xunit;
5+
6+
namespace DevExtreme.AspNet.Data.Tests {
7+
8+
public static class ExpandLinqSumTypeTestHelper {
9+
10+
public interface IEntity {
11+
Int32? Int32Prop { get; set; }
12+
Single? SingleProp { get; set; }
13+
}
14+
15+
public static IEnumerable<T> GenerateTestData<T>(Func<T> itemFactory) where T : IEntity {
16+
for(var i = 0; i < 2; i++) {
17+
var item = itemFactory();
18+
item.Int32Prop = Int32.MaxValue;
19+
item.SingleProp = Single.MaxValue;
20+
yield return item;
21+
}
22+
}
23+
24+
public static void Run<T>(IQueryable<T> data) {
25+
var loadResult = DataSourceLoader.Load(data, new SampleLoadOptions {
26+
RemoteGrouping = true,
27+
TotalSummary = new[] {
28+
new SummaryInfo { SummaryType = "sum", Selector = nameof(IEntity.Int32Prop) },
29+
new SummaryInfo { SummaryType = "sum", Selector = nameof(IEntity.SingleProp) }
30+
}
31+
});
32+
33+
var summary = loadResult.summary;
34+
35+
Assert.Equal(2m * Int32.MaxValue, summary[0]);
36+
Assert.Equal(2d * Single.MaxValue, summary[1]);
37+
}
38+
}
39+
40+
}

net/DevExtreme.AspNet.Data.Tests.EF6/DevExtreme.AspNet.Data.Tests.EF6.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
<Compile Include="Bug235.cs" />
8787
<Compile Include="Bug239.cs" />
8888
<Compile Include="Bug240.cs" />
89+
<Compile Include="ExpandLinqSumType.cs" />
8990
<Compile Include="PaginateViaPrimaryKey.cs" />
9091
<Compile Include="RemoteGroupingStress.cs" />
9192
<Compile Include="Summary.cs" />
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using Xunit;
4+
5+
namespace DevExtreme.AspNet.Data.Tests.EF6 {
6+
using DataItem = ExpandLinqSumType_DataItem;
7+
8+
class ExpandLinqSumType_DataItem : ExpandLinqSumTypeTestHelper.IEntity {
9+
public int ID { get; set; }
10+
public int? Int32Prop { get; set; }
11+
public float? SingleProp { get; set; }
12+
}
13+
14+
public class ExpandLinqSumType {
15+
16+
[Fact]
17+
public async Task Scenario() {
18+
await TestDbContext.ExecAsync(context => {
19+
var dbSet = context.Set<DataItem>();
20+
21+
dbSet.AddRange(ExpandLinqSumTypeTestHelper.GenerateTestData(() => new DataItem()));
22+
context.SaveChanges();
23+
24+
ExpandLinqSumTypeTestHelper.Run(dbSet);
25+
});
26+
}
27+
28+
}
29+
30+
}

net/DevExtreme.AspNet.Data.Tests.EF6/TestDbContext.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ protected override void OnModelCreating(DbModelBuilder modelBuilder) {
3333
modelBuilder.Entity<Summary_DataItem>();
3434
modelBuilder.Entity<PaginateViaPrimaryKey_DataItem>().HasKey(i => new { i.K1, i.K2 });
3535
modelBuilder.Entity<Async_DataItem>();
36+
modelBuilder.Entity<ExpandLinqSumType_DataItem>();
3637
}
3738

3839
public static async Task ExecAsync(Func<TestDbContext, Task> action) {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#if !EFCORE1 && !EFCORE2
2+
using System;
3+
using System.ComponentModel.DataAnnotations.Schema;
4+
using System.Threading.Tasks;
5+
using Xunit;
6+
7+
namespace DevExtreme.AspNet.Data.Tests.EFCore {
8+
9+
public class ExpandLinqSumType {
10+
11+
[Table(nameof(ExpandLinqSumType) + "_" + nameof(DataItem))]
12+
public class DataItem : ExpandLinqSumTypeTestHelper.IEntity {
13+
public int ID { get; set; }
14+
public int? Int32Prop { get; set; }
15+
public float? SingleProp { get; set; }
16+
}
17+
18+
[Fact]
19+
public async Task Scenario() {
20+
await TestDbContext.ExecAsync(context => {
21+
var dbSet = context.Set<DataItem>();
22+
23+
dbSet.AddRange(ExpandLinqSumTypeTestHelper.GenerateTestData(() => new DataItem()));
24+
context.SaveChanges();
25+
26+
ExpandLinqSumTypeTestHelper.Run(dbSet);
27+
});
28+
}
29+
30+
}
31+
}
32+
#endif

net/DevExtreme.AspNet.Data.Tests.EFCore/TestDbContext.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) {
2222
modelBuilder.Entity<Bug326.Entity>();
2323
modelBuilder.Entity<PaginateViaPrimaryKey.DataItem>().HasKey("K1", "K2");
2424
modelBuilder.Entity<Async.DataItem>();
25+
#if !EFCORE1 && !EFCORE2
26+
modelBuilder.Entity<ExpandLinqSumType.DataItem>();
27+
#endif
2528
}
2629

2730
public static async Task ExecAsync(Func<TestDbContext, Task> action) {
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using DevExpress.Xpo;
2+
using System;
3+
using System.Threading.Tasks;
4+
using Xunit;
5+
6+
namespace DevExtreme.AspNet.Data.Tests.Xpo {
7+
8+
public class ExpandLinqSumType {
9+
10+
[Persistent(nameof(ExpandLinqSumType) + "_" + nameof(DataItem))]
11+
public class DataItem : ExpandLinqSumTypeTestHelper.IEntity {
12+
[Key(AutoGenerate = true)]
13+
public int ID { get; set; }
14+
public int? Int32Prop { get; set; }
15+
public float? SingleProp { get; set; }
16+
}
17+
18+
[Fact]
19+
public async Task Scenario() {
20+
await UnitOfWorkHelper.ExecAsync(uow => {
21+
foreach(var i in ExpandLinqSumTypeTestHelper.GenerateTestData(() => new DataItem()))
22+
uow.Save(i);
23+
uow.CommitChanges();
24+
25+
ExpandLinqSumTypeTestHelper.Run(uow.Query<DataItem>());
26+
});
27+
}
28+
29+
}
30+
31+
}

net/DevExtreme.AspNet.Data.Tests.Xpo/UnitOfWorkHelper.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ public static async Task ExecAsync(Func<UnitOfWork, Task> action) {
2323
typeof(Summary.DataItem),
2424
typeof(Bug339.DataItem),
2525
typeof(PaginateViaPrimaryKey.DataItem),
26-
typeof(Async.DataItem)
26+
typeof(Async.DataItem),
27+
typeof(ExpandLinqSumType.DataItem)
2728
);
2829

2930
var provider = XpoDefault.GetConnectionProvider(

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public static Expression BuildCountExpr<T>(this DataSourceExpressionBuilder<T> b
1717
}
1818

1919
public static Expression BuildLoadGroupsExpr<T>(this DataSourceExpressionBuilder<T> builder) {
20-
return builder.BuildLoadGroupsExpr(CreateSourceExpr<T>());
20+
return builder.BuildLoadGroupsExpr(CreateSourceExpr<T>(), false);
2121
}
2222

2323
static Expression CreateSourceExpr<T>() {

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

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public void GroupInterval_Numeric() {
106106

107107
string Compile<T>(string selector, bool guardNulls) {
108108
var compiler = new RemoteGroupExpressionCompiler<T>(
109-
guardNulls, null,
109+
guardNulls, false, null,
110110
new[] {
111111
new GroupingInfo { Selector = selector, GroupInterval = "123" }
112112
},
@@ -130,7 +130,7 @@ public void GroupInterval_Date() {
130130

131131
string Compile<T>(string selector, bool guardNulls) {
132132
var compiler = new RemoteGroupExpressionCompiler<T>(
133-
guardNulls, null,
133+
guardNulls, false, null,
134134
new[] {
135135
new GroupingInfo { Selector = selector, GroupInterval = "year" },
136136
new GroupingInfo { Selector = selector, GroupInterval = "quarter" },
@@ -216,6 +216,52 @@ void Bug100Core<T>(params string[] memberNames) {
216216
);
217217
}
218218

219+
[Fact]
220+
public void GetSumType_ExpandFalse() {
221+
Type GetSumType<T>() => RemoteGroupExpressionCompiler<object>.GetSumType(typeof(T), false);
222+
223+
// Validation: check lambda type in new T[0].Sum(i => i)
224+
225+
Assert.Equal(typeof(int), GetSumType<sbyte>());
226+
Assert.Equal(typeof(int), GetSumType<byte>());
227+
228+
Assert.Equal(typeof(int), GetSumType<short>());
229+
Assert.Equal(typeof(int), GetSumType<ushort>());
230+
231+
Assert.Equal(typeof(int), GetSumType<int>());
232+
Assert.Equal(typeof(long), GetSumType<uint>());
233+
234+
Assert.Equal(typeof(long), GetSumType<long>());
235+
Assert.Equal(typeof(decimal), GetSumType<ulong>());
236+
237+
Assert.Equal(typeof(float), GetSumType<float>());
238+
Assert.Equal(typeof(double), GetSumType<double>());
239+
Assert.Equal(typeof(decimal), GetSumType<decimal>());
240+
}
241+
242+
[Fact]
243+
public void GetSumType_ExpandTrue() {
244+
Type GetSumType<T>() => RemoteGroupExpressionCompiler<object>.GetSumType(typeof(T), true);
245+
246+
// Don't convert integer types to decimal because SQL decimals have variable precision
247+
// Except for UInt64 for which there is no better choice
248+
249+
Assert.Equal(typeof(long), GetSumType<sbyte>());
250+
Assert.Equal(typeof(long), GetSumType<byte>());
251+
252+
Assert.Equal(typeof(long), GetSumType<short>());
253+
Assert.Equal(typeof(long), GetSumType<ushort>());
254+
255+
Assert.Equal(typeof(long), GetSumType<int>());
256+
Assert.Equal(typeof(long), GetSumType<uint>());
257+
258+
Assert.Equal(typeof(long), GetSumType<long>());
259+
Assert.Equal(typeof(decimal), GetSumType<ulong>());
260+
261+
Assert.Equal(typeof(double), GetSumType<float>());
262+
Assert.Equal(typeof(double), GetSumType<double>());
263+
Assert.Equal(typeof(decimal), GetSumType<decimal>());
264+
}
219265
}
220266

221267
}

0 commit comments

Comments
 (0)