Skip to content

Commit 39bf753

Browse files
lillo42hazzik
authored andcommitted
Fix Guid.ToString() (#1856)
Fixes #1151 Co-authored-by: Alexander Zaytsev <[email protected]>
1 parent 99dc4a9 commit 39bf753

File tree

13 files changed

+198
-3
lines changed

13 files changed

+198
-3
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by AsyncGenerator.
4+
//
5+
// Changes to this file may cause incorrect behavior and will be lost if
6+
// the code is regenerated.
7+
// </auto-generated>
8+
//------------------------------------------------------------------------------
9+
10+
11+
using System;
12+
using System.Linq;
13+
using NHibernate.Cfg.MappingSchema;
14+
using NHibernate.Mapping.ByCode;
15+
using NUnit.Framework;
16+
using NHibernate.Linq;
17+
18+
namespace NHibernate.Test.NHSpecificTest.NH3426
19+
{
20+
using System.Threading.Tasks;
21+
[TestFixture]
22+
public class FixtureAsync : TestCaseMappingByCode
23+
{
24+
25+
protected override HbmMapping GetMappings()
26+
{
27+
var mapper = new ModelMapper();
28+
mapper.Class<Entity>(rc =>
29+
{
30+
rc.Id(x => x.Id);
31+
rc.Property(x => x.Name);
32+
});
33+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
34+
}
35+
36+
private const string id = "9FF2D288-56E6-F349-9CFC-48902132D65B";
37+
38+
protected override void OnSetUp()
39+
{
40+
using (var session = OpenSession())
41+
{
42+
session.Save(new Entity { Id = Guid.Parse(id), Name = "Name 1" });
43+
44+
session.Flush();
45+
}
46+
}
47+
48+
protected override void OnTearDown()
49+
{
50+
using (var session = OpenSession())
51+
{
52+
using (var transaction = session.BeginTransaction())
53+
{
54+
session.Delete("from System.Object");
55+
56+
session.Flush();
57+
transaction.Commit();
58+
}
59+
}
60+
}
61+
62+
[Test]
63+
public async Task SelectGuidToStringAsync()
64+
{
65+
using (var session = OpenSession())
66+
{
67+
var list = await (session.Query<Entity>()
68+
.Select(x => new { Id = x.Id.ToString() })
69+
.ToListAsync());
70+
71+
Assert.AreEqual(id.ToUpper(), list[0].Id.ToUpper());
72+
}
73+
}
74+
75+
[Test]
76+
public async Task WhereGuidToStringAsync()
77+
{
78+
using (var session = OpenSession())
79+
{
80+
var list = await (session.Query<Entity>()
81+
.Where(x => x.Id.ToString().ToUpper() == id)
82+
.ToListAsync());
83+
84+
Assert.That(list, Has.Count.EqualTo(1));
85+
}
86+
}
87+
}
88+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System;
2+
3+
namespace NHibernate.Test.NHSpecificTest.NH3426
4+
{
5+
public class Entity
6+
{
7+
public virtual Guid Id { get; set; }
8+
public virtual string Name { get; set; }
9+
}
10+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using System;
2+
using System.Linq;
3+
using NHibernate.Cfg.MappingSchema;
4+
using NHibernate.Mapping.ByCode;
5+
using NUnit.Framework;
6+
7+
namespace NHibernate.Test.NHSpecificTest.NH3426
8+
{
9+
[TestFixture]
10+
public class Fixture : TestCaseMappingByCode
11+
{
12+
13+
protected override HbmMapping GetMappings()
14+
{
15+
var mapper = new ModelMapper();
16+
mapper.Class<Entity>(rc =>
17+
{
18+
rc.Id(x => x.Id);
19+
rc.Property(x => x.Name);
20+
});
21+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
22+
}
23+
24+
private const string id = "9FF2D288-56E6-F349-9CFC-48902132D65B";
25+
26+
protected override void OnSetUp()
27+
{
28+
using (var session = OpenSession())
29+
{
30+
session.Save(new Entity { Id = Guid.Parse(id), Name = "Name 1" });
31+
32+
session.Flush();
33+
}
34+
}
35+
36+
protected override void OnTearDown()
37+
{
38+
using (var session = OpenSession())
39+
{
40+
using (var transaction = session.BeginTransaction())
41+
{
42+
session.Delete("from System.Object");
43+
44+
session.Flush();
45+
transaction.Commit();
46+
}
47+
}
48+
}
49+
50+
[Test]
51+
public void SelectGuidToString()
52+
{
53+
using (var session = OpenSession())
54+
{
55+
var list = session.Query<Entity>()
56+
.Select(x => new { Id = x.Id.ToString() })
57+
.ToList();
58+
59+
Assert.AreEqual(id.ToUpper(), list[0].Id.ToUpper());
60+
}
61+
}
62+
63+
[Test]
64+
public void WhereGuidToString()
65+
{
66+
using (var session = OpenSession())
67+
{
68+
var list = session.Query<Entity>()
69+
.Where(x => x.Id.ToString().ToUpper() == id)
70+
.ToList();
71+
72+
Assert.That(list, Has.Count.EqualTo(1));
73+
}
74+
}
75+
}
76+
}

src/NHibernate.Test/NHibernate.Test.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
<PackageReference Include="NUnit" Version="3.10.1" />
5656
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
5757
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
58-
<PackageReference Include="FirebirdSql.Data.FirebirdClient" Version="5.12.1" />
58+
<PackageReference Include="FirebirdSql.Data.FirebirdClient" Version="6.3.0" />
5959
<PackageReference Include="Npgsql" Version="3.2.4.1" />
6060
</ItemGroup>
6161
<ItemGroup Condition="'$(TargetFramework)'=='net461'">

src/NHibernate/Dialect/Dialect.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ protected Dialect()
123123
RegisterFunction("bnot", new Function.BitwiseNativeOperation("~", true));
124124

125125
RegisterFunction("str", new SQLFunctionTemplate(NHibernateUtil.String, "cast(?1 as char)"));
126+
RegisterFunction("strguid", new SQLFunctionTemplate(NHibernateUtil.String, "?1"));
126127

127128
// register hibernate types for default use in scalar sqlquery type auto detection
128129
RegisterHibernateType(DbType.Int64, NHibernateUtil.Int64.Name);

src/NHibernate/Dialect/FirebirdDialect.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ private void OverrideStandardHQLFunctions()
419419
RegisterFunction("upper", new StandardSafeSQLFunction("upper", NHibernateUtil.String, 1));
420420
RegisterFunction("mod", new StandardSafeSQLFunction("mod", NHibernateUtil.Double, 2));
421421
RegisterFunction("str", new SQLFunctionTemplate(NHibernateUtil.String, "cast(?1 as VARCHAR(255))"));
422+
RegisterFunction("strguid", new StandardSQLFunction("uuid_to_char", NHibernateUtil.String));
422423
RegisterFunction("sysdate", new CastedFunction("today", NHibernateUtil.Date));
423424
RegisterFunction("date", new SQLFunctionTemplate(NHibernateUtil.Date, "cast(?1 as date)"));
424425
// Bitwise operations
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
using System.Data;
3+
using NHibernate.Dialect.Function;
34

45
namespace NHibernate.Dialect
56
{
@@ -8,6 +9,7 @@ public class MySQL55Dialect : MySQL5Dialect
89
public MySQL55Dialect()
910
{
1011
RegisterColumnType(DbType.Guid, "CHAR(36)");
12+
RegisterFunction("strguid", new SQLFunctionTemplate(NHibernateUtil.String, "?1"));
1113
}
1214
}
13-
}
15+
}

src/NHibernate/Dialect/MySQL5Dialect.cs

Lines changed: 5 additions & 1 deletion
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
@@ -11,9 +12,12 @@ public MySQL5Dialect()
1112
// My SQL supports precision up to 65, but .Net is limited to 28-29.
1213
RegisterColumnType(DbType.Decimal, 29, "DECIMAL($p, $s)");
1314
RegisterColumnType(DbType.Guid, "BINARY(16)");
15+
16+
RegisterFunction("strguid", new SQLFunctionTemplate(NHibernateUtil.String, "concat(hex(reverse(substr(?1, 1, 4))), '-', hex(reverse(substring(?1, 5, 2))), '-', hex(reverse(substr(?1, 7, 2))), '-', hex(substr(?1, 9, 2)), '-', hex(substr(?1, 11)))"));
1417
}
1518

16-
protected override void RegisterCastTypes() {
19+
protected override void RegisterCastTypes()
20+
{
1721
base.RegisterCastTypes();
1822
// MySql 5 also supports DECIMAL as a cast type target
1923
// http://dev.mysql.com/doc/refman/5.0/en/cast-functions.html

src/NHibernate/Dialect/Oracle8iDialect.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ protected virtual void RegisterFunctions()
302302
RegisterFunction("next_day", new StandardSQLFunction("next_day", NHibernateUtil.Date));
303303

304304
RegisterFunction("str", new StandardSQLFunction("to_char", NHibernateUtil.String));
305+
RegisterFunction("strguid", new SQLFunctionTemplate(NHibernateUtil.String, "substr(rawtohex(?1), 7, 2) || substr(rawtohex(?1), 5, 2) || substr(rawtohex(?1), 3, 2) || substr(rawtohex(?1), 1, 2) || '-' || substr(rawtohex(?1), 11, 2) || substr(rawtohex(?1), 9, 2) || '-' || substr(rawtohex(?1), 15, 2) || substr(rawtohex(?1), 13, 2) || '-' || substr(rawtohex(?1), 17, 4) || '-' || substr(rawtohex(?1), 21) "));
305306

306307
RegisterFunction("iif", new SQLFunctionTemplate(null, "case when ?1 then ?2 else ?3 end"));
307308

src/NHibernate/Dialect/PostgreSQLDialect.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ public PostgreSQLDialect()
9494

9595
// Register the date function, since when used in LINQ select clauses, NH must know the data type.
9696
RegisterFunction("date", new SQLFunctionTemplate(NHibernateUtil.Date, "cast(?1 as date)"));
97+
98+
RegisterFunction("strguid", new SQLFunctionTemplate(NHibernateUtil.String, "?1::TEXT"));
9799

98100
RegisterKeywords();
99101
}

src/NHibernate/Dialect/SQLiteDialect.cs

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

9595
// NH-3787: SQLite requires the cast in SQL too for not defaulting to string.
9696
RegisterFunction("transparentcast", new CastFunction());
97+
98+
RegisterFunction("strguid", new SQLFunctionTemplate(NHibernateUtil.String, "substr(hex(?1), 7, 2) || substr(hex(?1), 5, 2) || substr(hex(?1), 3, 2) || substr(hex(?1), 1, 2) || '-' || substr(hex(?1), 11, 2) || substr(hex(?1), 9, 2) || '-' || substr(hex(?1), 15, 2) || substr(hex(?1), 13, 2) || '-' || substr(hex(?1), 17, 4) || '-' || substr(hex(?1), 21) "));
9799
}
98100

99101
#region private static readonly string[] DialectKeywords = { ... }

src/NHibernate/Dialect/SybaseASE15Dialect.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ public SybaseASE15Dialect()
104104
RegisterFunction("sqrt", new StandardSQLFunction("sqrt", NHibernateUtil.Double));
105105
RegisterFunction("square", new StandardSQLFunction("square"));
106106
RegisterFunction("str", new StandardSQLFunction("str", NHibernateUtil.String));
107+
RegisterFunction("strguid", new StandardSQLFunction("str", NHibernateUtil.String));
107108
RegisterFunction("tan", new StandardSQLFunction("tan", NHibernateUtil.Double));
108109
RegisterFunction("trim", new AnsiTrimEmulationFunction("str_replace"));
109110
RegisterFunction("upper", new StandardSQLFunction("upper"));

src/NHibernate/Linq/Functions/StringGenerator.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,13 +317,20 @@ public IHqlGeneratorForMethod GetMethodGenerator(MethodInfo method)
317317

318318
public class ToStringHqlGeneratorForMethod : IHqlGeneratorForMethod
319319
{
320+
private static readonly System.Type _guidType = typeof(Guid);
321+
320322
public IEnumerable<MethodInfo> SupportedMethods
321323
{
322324
get { throw new NotSupportedException(); }
323325
}
324326

325327
public HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
326328
{
329+
if (targetObject.Type == _guidType)
330+
{
331+
return treeBuilder.MethodCall("strguid", visitor.Visit(targetObject).AsExpression());
332+
}
333+
327334
return treeBuilder.MethodCall("str", visitor.Visit(targetObject).AsExpression());
328335
}
329336
}

0 commit comments

Comments
 (0)