Skip to content

Commit 5550aad

Browse files
PaginateViaPrimaryKey option (#346)
1 parent 272745a commit 5550aad

15 files changed

Lines changed: 358 additions & 14 deletions

File tree

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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 class PaginateViaPrimaryKeyTestHelper {
9+
10+
public interface IDataItem {
11+
int K1 { get; set; }
12+
long K2 { get; set; }
13+
}
14+
15+
public static IEnumerable<T> CreateTestData<T>() where T : IDataItem, new() {
16+
for(var i = 1; i <= 3; i++)
17+
yield return new T { K1 = i, K2 = i };
18+
}
19+
20+
public static void Run<T>(IQueryable<T> source) {
21+
Run(source, new[] { "K1" });
22+
Run(source, new[] { "K1", "K2" });
23+
}
24+
25+
static void Run<T>(IQueryable<T> source, string[] pk) {
26+
var loadOptions = new SampleLoadOptions {
27+
PrimaryKey = pk,
28+
PaginateViaPrimaryKey = true,
29+
Filter = new[] { "K1", ">", "1" },
30+
Select = new[] { "K1", "K2" },
31+
Sort = new[] {
32+
new SortingInfo { Selector = "K1" }
33+
},
34+
Skip = 1,
35+
Take = 1,
36+
RequireTotalCount = true
37+
};
38+
39+
var loadResult = DataSourceLoader.Load(source, loadOptions);
40+
var data = loadResult.data.Cast<IDictionary<string, object>>().ToArray();
41+
42+
Assert.Single(data);
43+
Assert.Equal(3, data[0]["K1"]);
44+
}
45+
46+
}
47+
48+
}

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
@@ -84,6 +84,7 @@
8484
<Compile Include="Bug235.cs" />
8585
<Compile Include="Bug239.cs" />
8686
<Compile Include="Bug240.cs" />
87+
<Compile Include="PaginateViaPrimaryKey.cs" />
8788
<Compile Include="RemoteGroupingStress.cs" />
8889
<Compile Include="Summary.cs" />
8990
<Compile Include="SelectNotMapped.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.ComponentModel.DataAnnotations;
3+
using System.Linq;
4+
using Xunit;
5+
6+
namespace DevExtreme.AspNet.Data.Tests.EF6 {
7+
8+
public class PaginateViaPrimaryKey_DataItem : PaginateViaPrimaryKeyTestHelper.IDataItem {
9+
public int K1 { get; set; }
10+
public long K2 { get; set; }
11+
}
12+
13+
public class PaginateViaPrimaryKey {
14+
15+
[Fact]
16+
public void Scenario() {
17+
TestDbContext.Exec(context => {
18+
var set = context.Set<PaginateViaPrimaryKey_DataItem>();
19+
foreach(var i in PaginateViaPrimaryKeyTestHelper.CreateTestData<PaginateViaPrimaryKey_DataItem>())
20+
set.Add(i);
21+
context.SaveChanges();
22+
23+
PaginateViaPrimaryKeyTestHelper.Run(set);
24+
PaginateViaPrimaryKeyTestHelper.Run(set.Select(i => new { i.K1, i.K2 }));
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
@@ -32,6 +32,7 @@ protected override void OnModelCreating(DbModelBuilder modelBuilder) {
3232
modelBuilder.Entity<SelectNotMapped_DataItem>();
3333
modelBuilder.Entity<RemoteGroupingStress_DataItem>();
3434
modelBuilder.Entity<Summary_DataItem>();
35+
modelBuilder.Entity<PaginateViaPrimaryKey_DataItem>().HasKey(i => new { i.K1, i.K2 });
3536
}
3637

3738
public static void Exec(Action<TestDbContext> action) {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
using System.ComponentModel.DataAnnotations.Schema;
3+
using System.Linq;
4+
using Xunit;
5+
6+
namespace DevExtreme.AspNet.Data.Tests.EFCore2 {
7+
8+
public class PaginateViaPrimaryKey {
9+
10+
[Table(nameof(PaginateViaPrimaryKey) + "_" + nameof(DataItem))]
11+
public class DataItem : PaginateViaPrimaryKeyTestHelper.IDataItem {
12+
public int K1 { get; set; }
13+
public long K2 { get; set; }
14+
}
15+
16+
[Fact]
17+
public void Scenario() {
18+
TestDbContext.Exec(context => {
19+
var set = context.Set<DataItem>();
20+
set.AddRange(PaginateViaPrimaryKeyTestHelper.CreateTestData<DataItem>());
21+
context.SaveChanges();
22+
23+
PaginateViaPrimaryKeyTestHelper.Run(set);
24+
PaginateViaPrimaryKeyTestHelper.Run(set.Select(i => new { i.K1, i.K2 }));
25+
});
26+
}
27+
28+
}
29+
30+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) {
1818
modelBuilder.Entity<RemoteGroupingStress.DataItem>();
1919
modelBuilder.Entity<Summary.DataItem>();
2020
modelBuilder.Entity<Bug326.Entity>();
21+
modelBuilder.Entity<PaginateViaPrimaryKey.DataItem>().HasKey("K1", "K2");
2122
}
2223

2324
public static void Exec(Action<TestDbContext> action) {
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using FluentNHibernate.Mapping;
2+
using System;
3+
using System.Linq;
4+
using Xunit;
5+
6+
namespace DevExtreme.AspNet.Data.Tests.NH {
7+
8+
public class PaginateViaPrimaryKey {
9+
10+
public class DataItem : PaginateViaPrimaryKeyTestHelper.IDataItem {
11+
public virtual int K1 { get; set; }
12+
public virtual long K2 { get; set; }
13+
}
14+
15+
public class DataItemMap : ClassMap<DataItem> {
16+
public DataItemMap() {
17+
Table(nameof(PaginateViaPrimaryKey) + "_" + nameof(DataItem));
18+
Id(p => p.K1);
19+
Map(p => p.K2);
20+
}
21+
}
22+
23+
[Fact]
24+
public void Scenario() {
25+
SessionFactoryHelper.Exec(session => {
26+
foreach(var i in PaginateViaPrimaryKeyTestHelper.CreateTestData<DataItem>())
27+
session.Save(i);
28+
29+
var query = session.Query<DataItem>();
30+
PaginateViaPrimaryKeyTestHelper.Run(query);
31+
PaginateViaPrimaryKeyTestHelper.Run(query.Select(i => new { i.K1, i.K2 }));
32+
});
33+
}
34+
35+
}
36+
37+
}
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.Linq;
4+
using Xunit;
5+
6+
namespace DevExtreme.AspNet.Data.Tests.Xpo {
7+
8+
public class PaginateViaPrimaryKey {
9+
10+
[Persistent(nameof(PaginateViaPrimaryKey) + "_" + nameof(DataItem))]
11+
public class DataItem : PaginateViaPrimaryKeyTestHelper.IDataItem {
12+
[Key]
13+
public int K1 { get; set; }
14+
public long K2 { get; set; }
15+
}
16+
17+
[Fact]
18+
public void Scenario() {
19+
UnitOfWorkHelper.Exec(uow => {
20+
foreach(var i in PaginateViaPrimaryKeyTestHelper.CreateTestData<DataItem>())
21+
uow.Save(i);
22+
uow.CommitChanges();
23+
24+
var query = uow.Query<DataItem>();
25+
PaginateViaPrimaryKeyTestHelper.Run(query);
26+
PaginateViaPrimaryKeyTestHelper.Run(query.Select(i => new { i.K1, i.K2 }));
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
@@ -22,7 +22,8 @@ public static void Exec(Action<UnitOfWork> action) {
2222
typeof(DefaultSort.DataItem),
2323
typeof(RemoteGroupingStress.DataItem),
2424
typeof(Summary.DataItem),
25-
typeof(Bug339.DataItem)
25+
typeof(Bug339.DataItem),
26+
typeof(PaginateViaPrimaryKey.DataItem)
2627
);
2728

2829
var provider = XpoDefault.GetConnectionProvider(
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
using Newtonsoft.Json;
2+
using System;
3+
using System.Linq;
4+
using Xunit;
5+
6+
namespace DevExtreme.AspNet.Data.Tests {
7+
8+
public class PaginateViaPrimaryKeyTests {
9+
10+
[Fact]
11+
public void SingleKey() {
12+
var data = Enumerable.Range(0, 5)
13+
.Select(i => new { ID = i })
14+
.ToArray();
15+
16+
var loadOptions = new SampleLoadOptions {
17+
SuppressGuardNulls = true,
18+
19+
PrimaryKey = new[] { "ID" },
20+
PaginateViaPrimaryKey = true,
21+
22+
Filter = new[] { "ID", ">", "0" },
23+
24+
Skip = 2,
25+
Take = 2
26+
};
27+
28+
var loadResult = DataSourceLoader.Load(data, loadOptions);
29+
30+
Assert.Equal(
31+
"[{ID:3},{ID:4}]",
32+
DataToString(loadResult.data)
33+
);
34+
35+
var log = loadOptions.ExpressionLog;
36+
37+
Assert.EndsWith(
38+
".Where(obj => (obj.ID > 0))" +
39+
".OrderBy(obj => obj.ID)" +
40+
".Select(obj => new AnonType`1(I0 = obj.ID))" +
41+
".Skip(2).Take(2)",
42+
log[0]
43+
);
44+
45+
Assert.EndsWith(
46+
".Where(obj => ((obj.ID == 3) OrElse (obj.ID == 4)))" +
47+
".OrderBy(obj => obj.ID)",
48+
log[1]
49+
);
50+
}
51+
52+
[Fact]
53+
public void MultiKey() {
54+
var data = Enumerable.Range(0, 5)
55+
.Select(i => new { K1 = i, K2 = 5 - i })
56+
.ToArray();
57+
58+
var loadOptions = new SampleLoadOptions {
59+
SuppressGuardNulls = true,
60+
61+
PrimaryKey = new[] { "K1", "K2" },
62+
PaginateViaPrimaryKey = true,
63+
64+
Skip = 3,
65+
Take = 2
66+
};
67+
68+
DataSourceLoader.Load(data, loadOptions);
69+
70+
Assert.Contains(
71+
".Where(obj => (((obj.K1 == 3) AndAlso (obj.K2 == 2)) OrElse ((obj.K1 == 4) AndAlso (obj.K2 == 1))))",
72+
loadOptions.ExpressionLog[1]
73+
);
74+
}
75+
76+
[Fact]
77+
public void NotUsedWoSkip() {
78+
var loadOptions = new SampleLoadOptions {
79+
PaginateViaPrimaryKey = true,
80+
Take = 123
81+
};
82+
83+
DataSourceLoader.Load(new object[0], loadOptions);
84+
85+
Assert.All(
86+
loadOptions.ExpressionLog,
87+
i => Assert.DoesNotContain(".Select(", i)
88+
);
89+
}
90+
91+
[Fact]
92+
public void RequiresPrimaryKey() {
93+
var error = Record.Exception(delegate {
94+
DataSourceLoader.Load(new string[0], new SampleLoadOptions {
95+
PaginateViaPrimaryKey = true,
96+
Skip = 1
97+
});
98+
});
99+
Assert.True(error is InvalidOperationException);
100+
}
101+
102+
static string DataToString(object data) {
103+
return JsonConvert.SerializeObject(data).Replace("\"", "");
104+
}
105+
106+
}
107+
108+
}

0 commit comments

Comments
 (0)