Skip to content

Commit 3b836a3

Browse files
committed
Tests uses dotnet's LeftJoin if possible
1 parent b18cce6 commit 3b836a3

11 files changed

Lines changed: 612 additions & 40 deletions

Orm/Xtensive.Orm.Tests/Issues/IssueGithub0114_QueryRootReuseCauseNoRefJoin.cs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2023 Xtensive LLC.
1+
// Copyright (C) 2023-2026 Xtensive LLC.
22
// This code is distributed under MIT license terms.
33
// See the License.txt file in the project root for more information.
44

@@ -2380,6 +2380,50 @@ public void JoinQueryReuse()
23802380
}
23812381
}
23822382

2383+
#if NET10_0_OR_GREATER
2384+
[Test]
2385+
public void LeftJoinQueryReuse()
2386+
{
2387+
using (var session = Domain.OpenSession())
2388+
using (var tx = session.OpenTransaction()) {
2389+
var query = session.Query.All<Promotion>()
2390+
.Select(promo => new {
2391+
promo,
2392+
notifications = session.Query.All<Notification>()
2393+
.LeftJoin(session.Query.All<User>(), n => n.TriggeredBy.Id, u => u.Id, (n, u) => new { n, u })
2394+
})
2395+
.Select(anon => new {
2396+
contacted = anon.notifications.Select(c => c.n.Recipient.User.Id)
2397+
.Concat(anon.notifications.Select(c => c.n.Recipient.User.Id)),
2398+
promo = anon.promo
2399+
}).ToArray();
2400+
2401+
var expected = session.Query.All<Promotion>()
2402+
.Select(promo => new { promo })
2403+
.Select(anon => new {
2404+
contacted = session.Query.All<Notification>()
2405+
.LeftJoin(session.Query.All<User>(), n => n.TriggeredBy.Id, u => u.Id, (n, u) => new { n, u }).Select(c => c.n.Recipient.User.Id)
2406+
.Concat(session.Query.All<Notification>()
2407+
.LeftJoin(session.Query.All<User>(), n => n.TriggeredBy.Id, u => u.Id, (n, u) => new { n, u }).Select(c => c.n.Recipient.User.Id)),
2408+
promo = anon.promo
2409+
}).ToArray();
2410+
2411+
Assert.That(query.Length, Is.EqualTo(expected.Length));
2412+
2413+
for (var i = 0; i < expected.Length; i++) {
2414+
var a1 = expected[0];
2415+
var a2 = query[0];
2416+
2417+
var a1Contacted = a1.contacted.ToArray();
2418+
var a2Contacted = a2.contacted.ToArray();
2419+
2420+
Assert.That(a1.promo.Id, Is.EqualTo(a2.promo.Id));
2421+
Assert.That(a1Contacted.SequenceEqual(a2Contacted));
2422+
Assert.That(a1Contacted.Length, Is.Not.Zero);
2423+
}
2424+
}
2425+
}
2426+
#else
23832427
[Test]
23842428
public void LeftJoinQueryReuse()
23852429
{
@@ -2422,6 +2466,7 @@ public void LeftJoinQueryReuse()
24222466
}
24232467
}
24242468
}
2469+
#endif
24252470

24262471
[Test]
24272472
public void OfTypeQueryReuse()

Orm/Xtensive.Orm.Tests/Issues/IssueGithub0171_ReadDateTimeOffsetFromPackedTuple.cs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
// Copyright (C) 2021 Xtensive LLC.
1+
// Copyright (C) 2021-2026 Xtensive LLC.
22
// This code is distributed under MIT license terms.
33
// See the License.txt file in the project root for more information.
44

55
using System;
66
using System.Linq;
7-
using System.Threading.Tasks;
87
using NUnit.Framework;
98
using Xtensive.Orm.Configuration;
109
using Xtensive.Orm.Tests.Issues.IssueGithub0171_ReadDateTimeOffsetFromPackedTupleModel;
@@ -67,6 +66,54 @@ protected override void CheckRequirements()
6766
Require.ProviderIs(StorageProvider.SqlServer | StorageProvider.Oracle);
6867
}
6968

69+
#if NET10_0_OR_GREATER
70+
[Test]
71+
public void DateTimeOffsetCase()
72+
{
73+
using (var session = Domain.OpenSession())
74+
using (var tx = session.OpenTransaction()) {
75+
var expectedDateTimeOffset = new DateTimeOffset(2021, 9, 13, 0, 0, 1, new TimeSpan(5, 0, 0));
76+
var cargo = new Cargo(session) { DateTimeOffsetField = expectedDateTimeOffset };
77+
var loadNoCargo = new CargoLoad(session, null);
78+
var loadWithCargo = new CargoLoad(session, cargo);
79+
80+
var query = session.Query.All<CargoLoad>()
81+
.LeftJoin(session.Query.All<Cargo>(),
82+
cl => cl.Cargo,
83+
c => c,
84+
(cl, c) => new { CargoLoad = cl, Cargo = c })
85+
.Select(t => t.Cargo.DateTimeOffsetField)
86+
.ToArray();
87+
88+
Assert.That(query.Length, Is.EqualTo(2));
89+
Assert.That(query.Any(d => d == DateTimeOffset.MinValue), Is.True);
90+
Assert.That(query.Any(d => d == expectedDateTimeOffset), Is.True);
91+
}
92+
}
93+
94+
[Test]
95+
public void DateTimeCase()
96+
{
97+
using (var session = Domain.OpenSession())
98+
using (var tx = session.OpenTransaction()) {
99+
var expectedDateTime = new DateTime(2021, 9, 13, 0, 0, 1);
100+
var cargo = new Cargo(session) { DateTimeField = expectedDateTime };
101+
var loadNoCargo = new CargoLoad(session, null);
102+
var loadWithCargo = new CargoLoad(session, cargo);
103+
104+
var query = session.Query.All<CargoLoad>()
105+
.LeftJoin(session.Query.All<Cargo>(),
106+
cl => cl.Cargo,
107+
c => c,
108+
(cl, c) => new { CargoLoad = cl, Cargo = c })
109+
.Select(t => t.Cargo.DateTimeField)
110+
.ToArray();
111+
Assert.That(query.Length, Is.EqualTo(2));
112+
Assert.That(query.Any(d => d == DateTime.MinValue), Is.True);
113+
Assert.That(query.Any(d => d == expectedDateTime), Is.True);
114+
}
115+
}
116+
#else
70117
[Test]
71118
public void DateTimeOffsetCase()
72119
{
@@ -113,5 +160,6 @@ public void DateTimeCase()
113160
Assert.That(query.Any(d => d == expectedDateTime), Is.True);
114161
}
115162
}
163+
#endif
116164
}
117165
}

Orm/Xtensive.Orm.Tests/Issues/IssueJira0553_IncorrectLeftJoinOnNotNullEntityField.cs

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
// Copyright (C) 2014 Xtensive LLC.
2-
// All rights reserved.
3-
// For conditions of distribution and use, see license.
1+
// Copyright (C) 2014-2026 Xtensive LLC.
2+
// This code is distributed under MIT license terms.
3+
// See the License.txt file in the project root for more information.
44
// Created by: Alexey Kulakov
55
// Created: 2014.09.08
66

77
using System;
8-
using System.Collections.Generic;
98
using System.Linq;
10-
using System.Text;
119
using NUnit.Framework;
1210
using Xtensive.Orm.Configuration;
1311
using Xtensive.Orm.Tests.Issues.IssueJira0553_IncorrectLeftJoinOnNotNullEntityFieldModel;
@@ -130,6 +128,72 @@ protected override void PopulateData()
130128
}
131129
}
132130

131+
#if NET10_0_OR_GREATER
132+
[Test]
133+
public void BadWorkTest()
134+
{
135+
using (var session = Domain.OpenSession())
136+
using (var t = session.OpenTransaction()) {
137+
var badResult = session.Query.All<Employee>()
138+
.LeftJoin(
139+
session.Query.All<EmployeeWithCar>(),
140+
e => e.Id,
141+
ewc => ewc.Id,
142+
(e, ewc) => new {
143+
e.Id,
144+
CarObject = ewc.Car
145+
});
146+
147+
Assert.That(badResult.Count(), Is.EqualTo(3));
148+
}
149+
}
150+
151+
[Test]
152+
public void GoodWorkTest()
153+
{
154+
using (var session = Domain.OpenSession())
155+
using (var transaction = session.OpenTransaction()) {
156+
var goodResult = session.Query.All<Employee>()
157+
.LeftJoin(
158+
session.Query.All<EmployeeWithCar>(),
159+
e => e.Id,
160+
ewc => ewc.Id,
161+
(e, ewc) => new {
162+
e.Id,
163+
Car = ewc.Car.Id
164+
});
165+
Assert.That(goodResult.Count(), Is.EqualTo(3));
166+
}
167+
}
168+
169+
[Test]
170+
public void WorkaroundTest()
171+
{
172+
using (var session = Domain.OpenSession())
173+
using (var transaction = session.OpenTransaction()) {
174+
var wordaround = session.Query.All<Employee>()
175+
.LeftJoin(
176+
session.Query.All<EmployeeWithCar>(),
177+
e => e.Id,
178+
ewc => ewc.Id,
179+
(e, ewc) => new {
180+
e.Id,
181+
CarId = ewc.Car.Id
182+
})
183+
.LeftJoin(
184+
session.Query.All<Car>(),
185+
e => e.CarId,
186+
c => c.Id,
187+
(e, c) => new {
188+
e.Id,
189+
Car = c
190+
});
191+
192+
193+
Assert.That(wordaround.Count(), Is.EqualTo(3));
194+
}
195+
}
196+
#else
133197
[Test]
134198
public void BadWorkTest()
135199
{
@@ -194,6 +258,7 @@ public void WorkaroundTest()
194258
Assert.That(wordaround.Count(), Is.EqualTo(3));
195259
}
196260
}
261+
#endif
197262

198263
[Test]
199264
public void Test01()

Orm/Xtensive.Orm.Tests/Issues/IssueJira0584_IncorrectMappingOfColumnInQuery.cs

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2015-2023 Xtensive LLC.
1+
// Copyright (C) 2015-2026 Xtensive LLC.
22
// This code is distributed under MIT license terms.
33
// See the License.txt file in the project root for more information.
44
// Created by: Alexey Kulakov
@@ -474,7 +474,7 @@ public class IssueJira0584_IncorrectMappingOfColumnInQuery : AutoBuildTest
474474
{
475475
private ProviderKind? previousProviderKind;
476476

477-
[Test(Description = "Case when calculated column in the midle of selected columns averege")]
477+
[Test(Description = "Case when calculated column in the middle of selected columns averege")]
478478
public void IncludeProviderOptimizationTest01()
479479
{
480480
EnsureRightDateIsInStorage(ProviderKind.IncludeProvider);
@@ -526,8 +526,13 @@ public void IncludeProviderOptimizationTest01()
526526

527527
var usefulColumns = masterCredit.Union(masterDebit);
528528
var readyForFilterQuery = from joinResult in usefulColumns
529-
.LeftJoinEx(priceCalculation, a => a.SlaveAccount, a => a.Account, (pp, ps) => new {pp, ps})
530-
.LeftJoinEx(priceCalculation, a => a.pp.MasterAccount, a => a.Account, (a, pm) => new {a.pp, a.ps, pm})
529+
#if NET10_0_OR_GREATER
530+
.LeftJoin(priceCalculation, a => a.SlaveAccount, a => a.Account, (pp, ps) => new { pp, ps })
531+
.LeftJoin(priceCalculation, a => a.pp.MasterAccount, a => a.Account, (a, pm) => new { a.pp, a.ps, pm })
532+
#else
533+
.LeftJoinEx(priceCalculation, a => a.SlaveAccount, a => a.Account, (pp, ps) => new { pp, ps })
534+
.LeftJoinEx(priceCalculation, a => a.pp.MasterAccount, a => a.Account, (a, pm) => new { a.pp, a.ps, pm })
535+
#endif
531536
let item = joinResult.pp
532537
select new CustomPosting() {
533538
Id = item.Id,
@@ -609,9 +614,15 @@ public void IncludeProviderOptimizationTest02()
609614

610615
var usefulColumns = masterCredit.Union(masterDebit);
611616
var readyForFilterQuery = from joinResult in usefulColumns
612-
.LeftJoinEx(priceCalculation, a => a.SlaveAccount, a => a.Account, (pp, ps) => new {pp, ps})
613-
.LeftJoinEx(priceCalculation, a => a.pp.MasterAccount, a => a.Account, (a, pm) => new {a.pp, a.ps, pm})
614-
let item = joinResult.pp
617+
#if NET10_0_OR_GREATER
618+
.LeftJoin(priceCalculation, a => a.SlaveAccount, a => a.Account, (pp, ps) => new { pp, ps })
619+
.LeftJoin(priceCalculation, a => a.pp.MasterAccount, a => a.Account, (a, pm) => new { a.pp, a.ps, pm })
620+
#else
621+
.LeftJoinEx(priceCalculation, a => a.SlaveAccount, a => a.Account, (pp, ps) => new { pp, ps })
622+
.LeftJoinEx(priceCalculation, a => a.pp.MasterAccount, a => a.Account, (a, pm) => new { a.pp, a.ps, pm })
623+
#endif
624+
625+
let item = joinResult.pp
615626
select new CustomPosting {
616627
Id = item.Id,
617628
Status = item.Status,
@@ -692,8 +703,13 @@ public void IncludeProviderOptimizationTest03()
692703

693704
var usefulColumns = masterCredit.Union(masterDebit);
694705
var readyForFilterQuery = from joinResult in usefulColumns
695-
.LeftJoinEx(priceCalculation, a => a.SlaveAccount, a => a.Account, (pp, ps) => new {pp, ps})
696-
.LeftJoinEx(priceCalculation, a => a.pp.MasterAccount, a => a.Account, (a, pm) => new {a.pp, a.ps, pm})
706+
#if NET10_0_OR_GREATER
707+
.LeftJoin(priceCalculation, a => a.SlaveAccount, a => a.Account, (pp, ps) => new { pp, ps })
708+
.LeftJoin(priceCalculation, a => a.pp.MasterAccount, a => a.Account, (a, pm) => new { a.pp, a.ps, pm })
709+
#else
710+
.LeftJoinEx(priceCalculation, a => a.SlaveAccount, a => a.Account, (pp, ps) => new { pp, ps })
711+
.LeftJoinEx(priceCalculation, a => a.pp.MasterAccount, a => a.Account, (a, pm) => new { a.pp, a.ps, pm })
712+
#endif
697713
let item = joinResult.pp
698714
select new CustomPosting {
699715
Id = item.Id,
@@ -776,8 +792,13 @@ public void IncludeProviderOptimizationTest04()
776792

777793
var usefulColumns = masterCredit.Union(masterDebit);
778794
var readyForFilterQuery = from joinResult in usefulColumns
779-
.LeftJoinEx(priceCalculation, a => a.SlaveAccount, a => a.Account, (pp, ps) => new {pp, ps})
780-
.LeftJoinEx(priceCalculation, a => a.pp.MasterAccount, a => a.Account, (a, pm) => new {a.pp, a.ps, pm})
795+
#if NET10_0_OR_GREATER
796+
.LeftJoin(priceCalculation, a => a.SlaveAccount, a => a.Account, (pp, ps) => new { pp, ps })
797+
.LeftJoin(priceCalculation, a => a.pp.MasterAccount, a => a.Account, (a, pm) => new { a.pp, a.ps, pm })
798+
#else
799+
.LeftJoinEx(priceCalculation, a => a.SlaveAccount, a => a.Account, (pp, ps) => new { pp, ps })
800+
.LeftJoinEx(priceCalculation, a => a.pp.MasterAccount, a => a.Account, (a, pm) => new { a.pp, a.ps, pm })
801+
#endif
781802
let item = joinResult.pp
782803
select new CustomPosting {
783804
Id = item.Id,
@@ -859,8 +880,13 @@ public void IncludeProviderOptimizationTest05()
859880

860881
var usefulColumns = masterCredit.Union(masterDebit);
861882
var readyForFilterQuery = from joinResult in usefulColumns
862-
.LeftJoinEx(priceCalculation, a => a.SlaveAccount, a => a.Account, (pp, ps) => new {pp, ps})
863-
.LeftJoinEx(priceCalculation, a => a.pp.MasterAccount, a => a.Account, (a, pm) => new {a.pp, a.ps, pm})
883+
#if NET10_0_OR_GREATER
884+
.LeftJoin(priceCalculation, a => a.SlaveAccount, a => a.Account, (pp, ps) => new { pp, ps })
885+
.LeftJoin(priceCalculation, a => a.pp.MasterAccount, a => a.Account, (a, pm) => new { a.pp, a.ps, pm })
886+
#else
887+
.LeftJoinEx(priceCalculation, a => a.SlaveAccount, a => a.Account, (pp, ps) => new { pp, ps })
888+
.LeftJoinEx(priceCalculation, a => a.pp.MasterAccount, a => a.Account, (a, pm) => new { a.pp, a.ps, pm })
889+
#endif
864890
let item = joinResult.pp
865891
select new CustomPosting {
866892
Id = item.Id,
@@ -1028,8 +1054,13 @@ public void JoinAsSourceOfSetOperation()
10281054

10291055
var result =
10301056
from r in
1031-
preResult.Join(tp.Distinct(), a => a.MasterAccount, a => a.Account, (a, pm) => new {pp = a, pm})
1032-
.LeftJoinEx(Query.All<TablePartBase.FinToolKind>(), a => a.pm.FinToolKind, a => a.Id, (a, b) => new {pp = a.pp, pm = a.pm, fk = b})
1057+
#if NET10_0_OR_GREATER
1058+
preResult.Join(tp.Distinct(), a => a.MasterAccount, a => a.Account, (a, pm) => new { pp = a, pm })
1059+
.LeftJoin(Query.All<TablePartBase.FinToolKind>(), a => a.pm.FinToolKind, a => a.Id, (a, b) => new { pp = a.pp, pm = a.pm, fk = b })
1060+
#else
1061+
preResult.Join(tp.Distinct(), a => a.MasterAccount, a => a.Account, (a, pm) => new { pp = a, pm })
1062+
.LeftJoinEx(Query.All<TablePartBase.FinToolKind>(), a => a.pm.FinToolKind, a => a.Id, (a, b) => new { pp = a.pp, pm = a.pm, fk = b })
1063+
#endif
10331064
let q = r.pp
10341065
select
10351066
new {

0 commit comments

Comments
 (0)