Skip to content

Commit ea91804

Browse files
Support evaluation of Guid.NewGuid() on db side
Part of #959
1 parent 9535f3c commit ea91804

17 files changed

+252
-41
lines changed

src/NHibernate.Test/Async/Linq/PreEvaluationTests.cs

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ public async Task CanQueryByDateTimeNowAsync()
3939
{
4040
using (var spy = new SqlLogSpy())
4141
{
42-
var x = await (db.Orders.Where(o => o.OrderDate.Value < DateTime.Now).ToListAsync());
42+
var x = await (db.Orders.CountAsync(o => o.OrderDate.Value < DateTime.Now));
4343

44-
Assert.That(x, Has.Count.GreaterThan(0));
44+
Assert.That(x, Is.GreaterThan(0));
4545
AssertFunctionInSql("current_timestamp", spy);
4646
}
4747
}
@@ -51,7 +51,10 @@ public async Task CanSelectDateTimeNowAsync()
5151
{
5252
using (var spy = new SqlLogSpy())
5353
{
54-
var x = await (db.Orders.Select(o => new { id = o.OrderId, d = DateTime.Now }).ToListAsync());
54+
var x =
55+
await (db
56+
.Orders.Select(o => new { id = o.OrderId, d = DateTime.Now })
57+
.OrderBy(o => o.id).Take(1).ToListAsync());
5558

5659
Assert.That(x, Has.Count.GreaterThan(0));
5760
AssertFunctionInSql("current_timestamp", spy);
@@ -63,9 +66,9 @@ public async Task CanQueryByDateTimeUtcNowAsync()
6366
{
6467
using (var spy = new SqlLogSpy())
6568
{
66-
var x = await (db.Orders.Where(o => o.OrderDate.Value < DateTime.UtcNow).ToListAsync());
69+
var x = await (db.Orders.CountAsync(o => o.OrderDate.Value < DateTime.UtcNow));
6770

68-
Assert.That(x, Has.Count.GreaterThan(0));
71+
Assert.That(x, Is.GreaterThan(0));
6972
AssertFunctionInSql("current_utctimestamp", spy);
7073
}
7174
}
@@ -75,7 +78,10 @@ public async Task CanSelectDateTimeUtcNowAsync()
7578
{
7679
using (var spy = new SqlLogSpy())
7780
{
78-
var x = await (db.Orders.Select(o => new { id = o.OrderId, d = DateTime.UtcNow }).ToListAsync());
81+
var x =
82+
await (db
83+
.Orders.Select(o => new { id = o.OrderId, d = DateTime.UtcNow })
84+
.OrderBy(o => o.id).Take(1).ToListAsync());
7985

8086
Assert.That(x, Has.Count.GreaterThan(0));
8187
AssertFunctionInSql("current_utctimestamp", spy);
@@ -87,9 +93,9 @@ public async Task CanQueryByDateTimeTodayAsync()
8793
{
8894
using (var spy = new SqlLogSpy())
8995
{
90-
var x = await (db.Orders.Where(o => o.OrderDate.Value < DateTime.Today).ToListAsync());
96+
var x = await (db.Orders.CountAsync(o => o.OrderDate.Value < DateTime.Today));
9197

92-
Assert.That(x, Has.Count.GreaterThan(0));
98+
Assert.That(x, Is.GreaterThan(0));
9399
AssertFunctionInSql("current_date", spy);
94100
}
95101
}
@@ -99,7 +105,10 @@ public async Task CanSelectDateTimeTodayAsync()
99105
{
100106
using (var spy = new SqlLogSpy())
101107
{
102-
var x = await (db.Orders.Select(o => new { id = o.OrderId, d = DateTime.Today }).ToListAsync());
108+
var x =
109+
await (db
110+
.Orders.Select(o => new { id = o.OrderId, d = DateTime.Today })
111+
.OrderBy(o => o.id).Take(1).ToListAsync());
103112

104113
Assert.That(x, Has.Count.GreaterThan(0));
105114
AssertFunctionInSql("current_date", spy);
@@ -115,9 +124,9 @@ public async Task CanQueryByDateTimeOffsetTimeNowAsync()
115124
using (var spy = new SqlLogSpy())
116125
{
117126
var testDate = DateTimeOffset.Now.AddDays(-1);
118-
var x = await (db.Orders.Where(o => testDate < DateTimeOffset.Now).ToListAsync());
127+
var x = await (db.Orders.CountAsync(o => testDate < DateTimeOffset.Now));
119128

120-
Assert.That(x, Has.Count.GreaterThan(0));
129+
Assert.That(x, Is.GreaterThan(0));
121130
AssertFunctionInSql("current_timestamp_offset", spy);
122131
}
123132
}
@@ -130,7 +139,10 @@ public async Task CanSelectDateTimeOffsetNowAsync()
130139

131140
using (var spy = new SqlLogSpy())
132141
{
133-
var x = await (db.Orders.Select(o => new { id = o.OrderId, d = DateTimeOffset.Now }).ToListAsync());
142+
var x =
143+
await (db
144+
.Orders.Select(o => new { id = o.OrderId, d = DateTimeOffset.Now })
145+
.OrderBy(o => o.id).Take(1).ToListAsync());
134146

135147
Assert.That(x, Has.Count.GreaterThan(0));
136148
AssertFunctionInSql("current_timestamp_offset", spy);
@@ -146,9 +158,9 @@ public async Task CanQueryByDateTimeOffsetUtcNowAsync()
146158
using (var spy = new SqlLogSpy())
147159
{
148160
var testDate = DateTimeOffset.UtcNow.AddDays(-1);
149-
var x = await (db.Orders.Where(o => testDate < DateTimeOffset.UtcNow).ToListAsync());
161+
var x = await (db.Orders.CountAsync(o => testDate < DateTimeOffset.UtcNow));
150162

151-
Assert.That(x, Has.Count.GreaterThan(0));
163+
Assert.That(x, Is.GreaterThan(0));
152164
AssertFunctionInSql("current_utctimestamp_offset", spy);
153165
}
154166
}
@@ -161,13 +173,50 @@ public async Task CanSelectDateTimeOffsetUtcNowAsync()
161173

162174
using (var spy = new SqlLogSpy())
163175
{
164-
var x = await (db.Orders.Select(o => new { id = o.OrderId, d = DateTimeOffset.UtcNow }).ToListAsync());
176+
var x =
177+
await (db
178+
.Orders.Select(o => new { id = o.OrderId, d = DateTimeOffset.UtcNow })
179+
.OrderBy(o => o.id).Take(1).ToListAsync());
165180

166181
Assert.That(x, Has.Count.GreaterThan(0));
167182
AssertFunctionInSql("current_utctimestamp_offset", spy);
168183
}
169184
}
170185

186+
[Test]
187+
public async Task CanQueryByNewGuidAsync()
188+
{
189+
if (!TestDialect.SupportsSqlType(SqlTypeFactory.Guid))
190+
Assert.Ignore("Guid are not supported by the target database");
191+
192+
using (var spy = new SqlLogSpy())
193+
{
194+
var guid = Guid.NewGuid();
195+
var x = await (db.Orders.CountAsync(o => guid != Guid.NewGuid()));
196+
197+
Assert.That(x, Is.GreaterThan(0));
198+
AssertFunctionInSql("new_uuid", spy);
199+
}
200+
}
201+
202+
[Test]
203+
public async Task CanSelectNewGuidAsync()
204+
{
205+
if (!TestDialect.SupportsSqlType(SqlTypeFactory.Guid))
206+
Assert.Ignore("Guid are not supported by the target database");
207+
208+
using (var spy = new SqlLogSpy())
209+
{
210+
var x =
211+
await (db
212+
.Orders.Select(o => new { id = o.OrderId, g = Guid.NewGuid() })
213+
.OrderBy(o => o.id).Take(1).ToListAsync());
214+
215+
Assert.That(x, Has.Count.GreaterThan(0));
216+
AssertFunctionInSql("new_uuid", spy);
217+
}
218+
}
219+
171220
private void AssertFunctionInSql(string functionName, SqlLogSpy spy)
172221
{
173222
if (!IsFunctionSupported(functionName))

src/NHibernate.Test/Linq/PreEvaluationTests.cs

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ public void CanQueryByDateTimeNow()
2727
{
2828
using (var spy = new SqlLogSpy())
2929
{
30-
var x = db.Orders.Where(o => o.OrderDate.Value < DateTime.Now).ToList();
30+
var x = db.Orders.Count(o => o.OrderDate.Value < DateTime.Now);
3131

32-
Assert.That(x, Has.Count.GreaterThan(0));
32+
Assert.That(x, Is.GreaterThan(0));
3333
AssertFunctionInSql("current_timestamp", spy);
3434
}
3535
}
@@ -39,7 +39,10 @@ public void CanSelectDateTimeNow()
3939
{
4040
using (var spy = new SqlLogSpy())
4141
{
42-
var x = db.Orders.Select(o => new { id = o.OrderId, d = DateTime.Now }).ToList();
42+
var x =
43+
db
44+
.Orders.Select(o => new { id = o.OrderId, d = DateTime.Now })
45+
.OrderBy(o => o.id).Take(1).ToList();
4346

4447
Assert.That(x, Has.Count.GreaterThan(0));
4548
AssertFunctionInSql("current_timestamp", spy);
@@ -51,9 +54,9 @@ public void CanQueryByDateTimeUtcNow()
5154
{
5255
using (var spy = new SqlLogSpy())
5356
{
54-
var x = db.Orders.Where(o => o.OrderDate.Value < DateTime.UtcNow).ToList();
57+
var x = db.Orders.Count(o => o.OrderDate.Value < DateTime.UtcNow);
5558

56-
Assert.That(x, Has.Count.GreaterThan(0));
59+
Assert.That(x, Is.GreaterThan(0));
5760
AssertFunctionInSql("current_utctimestamp", spy);
5861
}
5962
}
@@ -63,7 +66,10 @@ public void CanSelectDateTimeUtcNow()
6366
{
6467
using (var spy = new SqlLogSpy())
6568
{
66-
var x = db.Orders.Select(o => new { id = o.OrderId, d = DateTime.UtcNow }).ToList();
69+
var x =
70+
db
71+
.Orders.Select(o => new { id = o.OrderId, d = DateTime.UtcNow })
72+
.OrderBy(o => o.id).Take(1).ToList();
6773

6874
Assert.That(x, Has.Count.GreaterThan(0));
6975
AssertFunctionInSql("current_utctimestamp", spy);
@@ -75,9 +81,9 @@ public void CanQueryByDateTimeToday()
7581
{
7682
using (var spy = new SqlLogSpy())
7783
{
78-
var x = db.Orders.Where(o => o.OrderDate.Value < DateTime.Today).ToList();
84+
var x = db.Orders.Count(o => o.OrderDate.Value < DateTime.Today);
7985

80-
Assert.That(x, Has.Count.GreaterThan(0));
86+
Assert.That(x, Is.GreaterThan(0));
8187
AssertFunctionInSql("current_date", spy);
8288
}
8389
}
@@ -87,7 +93,10 @@ public void CanSelectDateTimeToday()
8793
{
8894
using (var spy = new SqlLogSpy())
8995
{
90-
var x = db.Orders.Select(o => new { id = o.OrderId, d = DateTime.Today }).ToList();
96+
var x =
97+
db
98+
.Orders.Select(o => new { id = o.OrderId, d = DateTime.Today })
99+
.OrderBy(o => o.id).Take(1).ToList();
91100

92101
Assert.That(x, Has.Count.GreaterThan(0));
93102
AssertFunctionInSql("current_date", spy);
@@ -103,9 +112,9 @@ public void CanQueryByDateTimeOffsetTimeNow()
103112
using (var spy = new SqlLogSpy())
104113
{
105114
var testDate = DateTimeOffset.Now.AddDays(-1);
106-
var x = db.Orders.Where(o => testDate < DateTimeOffset.Now).ToList();
115+
var x = db.Orders.Count(o => testDate < DateTimeOffset.Now);
107116

108-
Assert.That(x, Has.Count.GreaterThan(0));
117+
Assert.That(x, Is.GreaterThan(0));
109118
AssertFunctionInSql("current_timestamp_offset", spy);
110119
}
111120
}
@@ -118,7 +127,10 @@ public void CanSelectDateTimeOffsetNow()
118127

119128
using (var spy = new SqlLogSpy())
120129
{
121-
var x = db.Orders.Select(o => new { id = o.OrderId, d = DateTimeOffset.Now }).ToList();
130+
var x =
131+
db
132+
.Orders.Select(o => new { id = o.OrderId, d = DateTimeOffset.Now })
133+
.OrderBy(o => o.id).Take(1).ToList();
122134

123135
Assert.That(x, Has.Count.GreaterThan(0));
124136
AssertFunctionInSql("current_timestamp_offset", spy);
@@ -134,9 +146,9 @@ public void CanQueryByDateTimeOffsetUtcNow()
134146
using (var spy = new SqlLogSpy())
135147
{
136148
var testDate = DateTimeOffset.UtcNow.AddDays(-1);
137-
var x = db.Orders.Where(o => testDate < DateTimeOffset.UtcNow).ToList();
149+
var x = db.Orders.Count(o => testDate < DateTimeOffset.UtcNow);
138150

139-
Assert.That(x, Has.Count.GreaterThan(0));
151+
Assert.That(x, Is.GreaterThan(0));
140152
AssertFunctionInSql("current_utctimestamp_offset", spy);
141153
}
142154
}
@@ -149,13 +161,50 @@ public void CanSelectDateTimeOffsetUtcNow()
149161

150162
using (var spy = new SqlLogSpy())
151163
{
152-
var x = db.Orders.Select(o => new { id = o.OrderId, d = DateTimeOffset.UtcNow }).ToList();
164+
var x =
165+
db
166+
.Orders.Select(o => new { id = o.OrderId, d = DateTimeOffset.UtcNow })
167+
.OrderBy(o => o.id).Take(1).ToList();
153168

154169
Assert.That(x, Has.Count.GreaterThan(0));
155170
AssertFunctionInSql("current_utctimestamp_offset", spy);
156171
}
157172
}
158173

174+
[Test]
175+
public void CanQueryByNewGuid()
176+
{
177+
if (!TestDialect.SupportsSqlType(SqlTypeFactory.Guid))
178+
Assert.Ignore("Guid are not supported by the target database");
179+
180+
using (var spy = new SqlLogSpy())
181+
{
182+
var guid = Guid.NewGuid();
183+
var x = db.Orders.Count(o => guid != Guid.NewGuid());
184+
185+
Assert.That(x, Is.GreaterThan(0));
186+
AssertFunctionInSql("new_uuid", spy);
187+
}
188+
}
189+
190+
[Test]
191+
public void CanSelectNewGuid()
192+
{
193+
if (!TestDialect.SupportsSqlType(SqlTypeFactory.Guid))
194+
Assert.Ignore("Guid are not supported by the target database");
195+
196+
using (var spy = new SqlLogSpy())
197+
{
198+
var x =
199+
db
200+
.Orders.Select(o => new { id = o.OrderId, g = Guid.NewGuid() })
201+
.OrderBy(o => o.id).Take(1).ToList();
202+
203+
Assert.That(x, Has.Count.GreaterThan(0));
204+
AssertFunctionInSql("new_uuid", spy);
205+
}
206+
}
207+
159208
private void AssertFunctionInSql(string functionName, SqlLogSpy spy)
160209
{
161210
if (!IsFunctionSupported(functionName))

src/NHibernate/Dialect/FirebirdDialect.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ private void OverrideStandardHQLFunctions()
422422
RegisterFunction("str", new SQLFunctionTemplate(NHibernateUtil.String, "cast(?1 as VARCHAR(255))"));
423423
RegisterFunction("sysdate", new CastedFunction("today", NHibernateUtil.Date));
424424
RegisterFunction("date", new SQLFunctionTemplate(NHibernateUtil.Date, "cast(?1 as date)"));
425+
RegisterFunction("new_uuid", new NoArgSQLFunction("gen_uuid", NHibernateUtil.Guid));
425426
// Bitwise operations
426427
RegisterFunction("band", new Function.BitwiseFunctionOperation("bin_and"));
427428
RegisterFunction("bor", new Function.BitwiseFunctionOperation("bin_or"));

src/NHibernate/Dialect/HanaDialectBase.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ protected virtual void RegisterNHibernateFunctions()
395395
RegisterFunction("iif", new SQLFunctionTemplate(null, "case when ?1 then ?2 else ?3 end"));
396396
RegisterFunction("sysdate", new NoArgSQLFunction("current_timestamp", NHibernateUtil.DateTime, false));
397397
RegisterFunction("truncate", new SQLFunctionTemplateWithRequiredParameters(null, "floor(?1 * power(10, ?2)) / power(10, ?2)", new object[] { null, "0" }));
398+
RegisterFunction("new_uuid", new NoArgSQLFunction("sysuuid", NHibernateUtil.Guid, false));
398399
}
399400

400401
protected virtual void RegisterHANAFunctions()

src/NHibernate/Dialect/MsSql2000Dialect.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,8 @@ protected virtual void RegisterFunctions()
359359

360360
RegisterFunction("bit_length", new SQLFunctionTemplate(NHibernateUtil.Int32, "datalength(?1) * 8"));
361361
RegisterFunction("extract", new SQLFunctionTemplate(NHibernateUtil.Int32, "datepart(?1, ?3)"));
362+
363+
RegisterFunction("new_uuid", new NoArgSQLFunction("newid", NHibernateUtil.Guid));
362364
}
363365

364366
protected virtual void RegisterGuidTypeMapping()

src/NHibernate/Dialect/MsSqlCeDialect.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@ protected virtual void RegisterFunctions()
200200

201201
RegisterFunction("bit_length", new SQLFunctionTemplate(NHibernateUtil.Int32, "datalength(?1) * 8"));
202202
RegisterFunction("extract", new SQLFunctionTemplate(NHibernateUtil.Int32, "datepart(?1, ?3)"));
203+
204+
RegisterFunction("new_uuid", new NoArgSQLFunction("newid", NHibernateUtil.Guid));
203205
}
204206

205207
protected virtual void RegisterDefaultProperties()

src/NHibernate/Dialect/MySQL5Dialect.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Data;
2+
using NHibernate.Dialect.Function;
23
using NHibernate.SqlCommand;
34

45
namespace NHibernate.Dialect
@@ -13,6 +14,13 @@ public MySQL5Dialect()
1314
RegisterColumnType(DbType.Guid, "BINARY(16)");
1415
}
1516

17+
protected override void RegisterFunctions()
18+
{
19+
base.RegisterFunctions();
20+
21+
RegisterFunction("new_uuid", new NoArgSQLFunction("uuid", NHibernateUtil.Guid));
22+
}
23+
1624
protected override void RegisterCastTypes() {
1725
base.RegisterCastTypes();
1826
// MySql 5 also supports DECIMAL as a cast type target

src/NHibernate/Dialect/Oracle8iDialect.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,8 @@ protected virtual void RegisterFunctions()
309309
RegisterFunction("bor", new SQLFunctionTemplate(null, "?1 + ?2 - BITAND(?1, ?2)"));
310310
RegisterFunction("bxor", new SQLFunctionTemplate(null, "?1 + ?2 - BITAND(?1, ?2) * 2"));
311311
RegisterFunction("bnot", new SQLFunctionTemplate(null, "(-1 - ?1)"));
312+
313+
RegisterFunction("new_uuid", new NoArgSQLFunction("sys_guid", NHibernateUtil.Guid));
312314
}
313315

314316
protected internal virtual void RegisterDefaultProperties()

src/NHibernate/Dialect/PostgreSQLDialect.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ public PostgreSQLDialect()
9696
RegisterFunction("date", new SQLFunctionTemplate(NHibernateUtil.Date, "cast(?1 as date)"));
9797
RegisterFunction("current_date", new NoArgSQLFunction("current_date", NHibernateUtil.Date, false));
9898

99+
// The uuid_generate_v4 is not native and must be installed, but SelectGUIDString property already uses it,
100+
// and NHibernate.TestDatabaseSetup does install it.
101+
RegisterFunction("new_uuid", new NoArgSQLFunction("uuid_generate_v4", NHibernateUtil.Guid));
102+
99103
RegisterKeywords();
100104
}
101105

0 commit comments

Comments
 (0)