Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c8e1129

Browse files
Don't join fkey table when linq comparison with composite id (#3629)
1 parent 67d06ee commit c8e1129

29 files changed

+334
-21
lines changed

‎.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
*.cmd text
1212
*.msbuild text
1313
*.md text
14+
*.sql text
1415

1516
*.sln text eol=crlf
1617
*.csproj text eol=crlf

‎src/NHibernate.DomainModel/NHibernate.DomainModel.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@
1515
<ItemGroup>
1616
<ProjectReference Include="..\NHibernate\NHibernate.csproj" />
1717
</ItemGroup>
18+
<ItemGroup>
19+
<PackageReference Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
20+
</ItemGroup>
1821
</Project>

‎src/NHibernate.DomainModel/Northwind/Entities/AnotherEntity.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ public class AnotherEntity
44
{
55
public virtual int Id { get; set; }
66
public virtual string Output { get; set; }
7-
public virtual string Input { get; set; }
7+
public virtual string Input { get; set; }
8+
public virtual CompositeIdEntity CompositeIdEntity { get; set; }
89
}
9-
}
10+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System;
2+
3+
namespace NHibernate.DomainModel.Northwind.Entities
4+
{
5+
public class CompositeId : IComparable<CompositeId>
6+
{
7+
public int ObjectId { get; set; }
8+
public int TenantId { get; set; }
9+
10+
public CompositeId() { }
11+
public CompositeId(int objectId, int tenantId)
12+
{
13+
ObjectId = objectId;
14+
TenantId = tenantId;
15+
}
16+
17+
public override string ToString() => ObjectId + "|" + TenantId;
18+
protected bool Equals(CompositeId other) => ObjectId == other.ObjectId && TenantId == other.TenantId;
19+
public static bool operator ==(CompositeId left, CompositeId right) => Equals(left, right);
20+
public static bool operator !=(CompositeId left, CompositeId right) => !Equals(left, right);
21+
22+
public override bool Equals(object obj)
23+
{
24+
if (ReferenceEquals(null, obj) || obj.GetType() != this.GetType())
25+
{
26+
return false;
27+
}
28+
return ReferenceEquals(this, obj) || Equals((CompositeId)obj);
29+
}
30+
31+
public override int GetHashCode() => HashCode.Combine(ObjectId, TenantId);
32+
33+
public int CompareTo(CompositeId other)
34+
{
35+
if (ReferenceEquals(this, other))
36+
{
37+
return 0;
38+
}
39+
else if (ReferenceEquals(other, null))
40+
{
41+
return 1;
42+
}
43+
44+
var idComparison = ObjectId.CompareTo(other.ObjectId);
45+
if (idComparison != 0)
46+
{
47+
return idComparison;
48+
}
49+
50+
return TenantId.CompareTo(other);
51+
}
52+
}
53+
public class CompositeIdEntity
54+
{
55+
public virtual CompositeId Id { get; set; }
56+
public virtual string Name { get; set; }
57+
}
58+
}

‎src/NHibernate.DomainModel/Northwind/Entities/Northwind.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ public IQueryable<Timesheet> Timesheets
5959
get { return _session.Query<Timesheet>(); }
6060
}
6161

62-
public IQueryable<Animal> Animals
63-
{
64-
get { return _session.Query<Animal>(); }
65-
}
62+
public IQueryable<Animal> Animals
63+
{
64+
get { return _session.Query<Animal>(); }
65+
}
6666

6767
public IQueryable<Mammal> Mammals
6868
{
@@ -113,5 +113,10 @@ public IQueryable<IUser> IUsers
113113
{
114114
get { return _session.Query<IUser>(); }
115115
}
116+
117+
public IQueryable<AnotherEntity> AnotherEntity
118+
{
119+
get { return _session.Query<AnotherEntity>(); }
120+
}
116121
}
117122
}

‎src/NHibernate.DomainModel/Northwind/Mappings/AnotherEntity.hbm.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,9 @@
66
</id>
77
<property name="Output" />
88
<property name="Input" />
9+
<many-to-one name="CompositeIdEntity" fetch="select">
10+
<column name="CompositeObjectId" />
11+
<column name="CompositeTenantId" />
12+
</many-to-one>
913
</class>
1014
</hibernate-mapping>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="NHibernate.DomainModel.Northwind.Entities" assembly="NHibernate.DomainModel">
3+
<class name="CompositeIdEntity" table="CompositeIdEntity">
4+
<composite-id name="Id">
5+
<key-property name="ObjectId" column="ObjectId" />
6+
<key-property name="TenantId" column="TenantId" />
7+
</composite-id>
8+
<property name="Name" length="128" />
9+
</class>
10+
</hibernate-mapping>

‎src/NHibernate.Test/Async/CompositeId/CompositeIdFixture.cs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
namespace NHibernate.Test.CompositeId
1919
{
2020
using System.Threading.Tasks;
21+
using System.Threading;
2122
[TestFixture]
2223
public class CompositeIdFixtureAsync : TestCase
2324
{
@@ -33,7 +34,7 @@ protected override string[] Mappings
3334
return new string[]
3435
{
3536
"CompositeId.Customer.hbm.xml", "CompositeId.Order.hbm.xml", "CompositeId.LineItem.hbm.xml",
36-
"CompositeId.Product.hbm.xml"
37+
"CompositeId.Product.hbm.xml","CompositeId.Shipper.hbm.xml"
3738
};
3839
}
3940
}
@@ -76,9 +77,13 @@ public async Task CompositeIdsAsync()
7677

7778
Order o = new Order(c);
7879
o.OrderDate = DateTime.Today;
80+
o.Shipper = new Shipper() { Id = new NullableId(null, 13) };
81+
await (s.PersistAsync(o));
82+
7983
LineItem li = new LineItem(o, p);
8084
li.Quantity = 2;
81-
85+
await (s.PersistAsync(li));
86+
8287
await (t.CommitAsync());
8388
}
8489

@@ -135,6 +140,19 @@ public async Task CompositeIdsAsync()
135140
await (t.CommitAsync());
136141
}
137142

143+
using (s = OpenSession())
144+
{
145+
t = s.BeginTransaction();
146+
var noShippersForWarehouse = await (s.Query<Order>()
147+
// NOTE: .Where(x => x.Shipper.Id == new NullableId(null, 13)) improperly renders
148+
// "where (ShipperId = @p1 and WarehouseId = @p2)" with @p1 = NULL (needs to be is null)
149+
// But the effort to fix is pretty high due to how component tuples are managed in linq / hql.
150+
.Where(x => x.Shipper.Id.WarehouseId == 13 && x.Shipper.Id.Id == null)
151+
.ToListAsync());
152+
Assert.AreEqual(1, noShippersForWarehouse.Count);
153+
await (t.CommitAsync());
154+
}
155+
138156
using (s = OpenSession())
139157
{
140158
t = s.BeginTransaction();
@@ -303,5 +321,14 @@ public async Task AnyOnCompositeIdAsync()
303321
await (s.Query<Order>().Select(o => o.LineItems.Any()).ToListAsync());
304322
}
305323
}
324+
325+
public async Task NullCompositeIdAsync(CancellationToken cancellationToken = default(CancellationToken))
326+
{
327+
using (var s = OpenSession())
328+
{
329+
await (s.Query<Order>().Where(o => o.LineItems.Any()).ToListAsync(cancellationToken));
330+
await (s.Query<Order>().Select(o => o.LineItems.Any()).ToListAsync(cancellationToken));
331+
}
332+
}
306333
}
307334
}

‎src/NHibernate.Test/Async/Linq/JoinTests.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,17 @@ public async Task OrderLinesWithSelectingCustomerNameInCaseShouldProduceTwoJoins
297297
Assert.That(countJoins, Is.EqualTo(2));
298298
}
299299
}
300+
301+
[Test]
302+
public async Task ShouldConstipateJoinsWhenOnlyComparingCompositeIdPropertiesAsync()
303+
{
304+
using (var spy = new SqlLogSpy())
305+
{
306+
await (db.AnotherEntity.Where(x => x.CompositeIdEntity.Id.TenantId == 3).ToListAsync());
307+
var countJoins = CountJoins(spy);
308+
Assert.That(countJoins, Is.EqualTo(0));
309+
}
310+
}
300311

301312
private static int CountJoins(LogSpy sqlLog)
302313
{

‎src/NHibernate.Test/Async/QueryTranslator/CustomQueryLoaderFixture.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ internal sealed class CustomQueryLoaderFixtureAsync : TestCase
4242
"Northwind.Mappings.TimeSheet.hbm.xml",
4343
"Northwind.Mappings.Animal.hbm.xml",
4444
"Northwind.Mappings.Patient.hbm.xml",
45-
"Northwind.Mappings.NumericEntity.hbm.xml"
45+
"Northwind.Mappings.NumericEntity.hbm.xml",
46+
"Northwind.Mappings.CompositeIdEntity.hbm.xml"
4647
};
4748

4849
protected override string MappingsAssembly => "NHibernate.DomainModel";

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /