From 967a190928471437bdb8c57d2d270aca459c2dbf Mon Sep 17 00:00:00 2001 From: Darren Reid Date: Wed, 24 Feb 2021 11:12:19 +1100 Subject: [PATCH 1/3] Fix for when table class has reference type (treated as TEXT or JSON column) and is provided null. Previously generated `{}` for null values with if inserted and then retrieved results in different instance values. --- .../OrmLiteDialectProviderBase.cs | 2 +- .../Shared/Person.cs | 45 +++++++++++++++++++ .../ToInsertAndUpdateStatementTests.cs | 17 +++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/ServiceStack.OrmLite/OrmLiteDialectProviderBase.cs b/src/ServiceStack.OrmLite/OrmLiteDialectProviderBase.cs index adcbdf97e..db1bcb377 100644 --- a/src/ServiceStack.OrmLite/OrmLiteDialectProviderBase.cs +++ b/src/ServiceStack.OrmLite/OrmLiteDialectProviderBase.cs @@ -1614,7 +1614,7 @@ protected virtual string FkOptionToString(OnFkOption option) public virtual string GetQuotedValue(object value, Type fieldType) { - if (value == null) + if (value == null || value == DBNull.Value) return "NULL"; var converter = value.GetType().IsEnum diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/Person.cs b/tests/ServiceStack.OrmLite.Tests/Shared/Person.cs index 62429a3e3..d51f13424 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/Person.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/Person.cs @@ -105,4 +105,49 @@ public enum Gender Male } + public class PersonWithReferenceType + { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public Person BestFriend { get; set; } + + public static PersonWithReferenceType[] TestValues = new[] + { + new PersonWithReferenceType + { + FirstName = "Test", + LastName = "McTest", + Id = 1 + } + }; + + protected bool Equals(PersonWithReferenceType other) + { + return Id == other.Id && + string.Equals(FirstName, other.FirstName) && + string.Equals(LastName, other.LastName) && + ((BestFriend == null && other.BestFriend == null) || (BestFriend != null && BestFriend.Equals(other.BestFriend))) ; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((PersonWithReferenceType)obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = Id; + hashCode = (hashCode * 397) ^ (FirstName != null ? FirstName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (LastName != null ? LastName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (BestFriend != null ? BestFriend.GetHashCode() : 0); + return hashCode; + } + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/ToInsertAndUpdateStatementTests.cs b/tests/ServiceStack.OrmLite.Tests/ToInsertAndUpdateStatementTests.cs index 278663d36..a55fbb7e7 100644 --- a/tests/ServiceStack.OrmLite.Tests/ToInsertAndUpdateStatementTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/ToInsertAndUpdateStatementTests.cs @@ -45,5 +45,22 @@ public void Can_use_ToInsertStatement_to_generate_inline_SQL() Assert.That(insertedRow.Equals(row)); } } + + [Test] + public void Correct_DbNull_in_ToInsertStatement() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + var row = PersonWithReferenceType.TestValues[0]; + + var sql = db.ToInsertStatement(row); + sql.Print(); + db.ExecuteSql(sql); + + var insertedRow = db.SingleById(row.Id); + Assert.That(insertedRow.Equals(row)); + } + } } } \ No newline at end of file From 4d1e654728b74f5a37199ee4bde11df4df091f79 Mon Sep 17 00:00:00 2001 From: Darren Reid Date: Wed, 24 Feb 2021 11:16:17 +1100 Subject: [PATCH 2/3] Add additional test for ToInsertAndUpdateStatementTests.cs for ref with populated values. --- .../ServiceStack.OrmLite.Tests/Shared/Person.cs | 7 +++++++ .../ToInsertAndUpdateStatementTests.cs | 17 +++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/Person.cs b/tests/ServiceStack.OrmLite.Tests/Shared/Person.cs index d51f13424..7e4667aff 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/Person.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/Person.cs @@ -119,6 +119,13 @@ public class PersonWithReferenceType FirstName = "Test", LastName = "McTest", Id = 1 + }, + new PersonWithReferenceType + { + FirstName = "John", + LastName = "Doe", + Id = 2, + BestFriend = new Person(1,"Jane","Doe",33) } }; diff --git a/tests/ServiceStack.OrmLite.Tests/ToInsertAndUpdateStatementTests.cs b/tests/ServiceStack.OrmLite.Tests/ToInsertAndUpdateStatementTests.cs index a55fbb7e7..edaeaff7a 100644 --- a/tests/ServiceStack.OrmLite.Tests/ToInsertAndUpdateStatementTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/ToInsertAndUpdateStatementTests.cs @@ -62,5 +62,22 @@ public void Correct_DbNull_in_ToInsertStatement() Assert.That(insertedRow.Equals(row)); } } + + [Test] + public void Correct_Ref_in_ToInsertStatement() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + var row = PersonWithReferenceType.TestValues[1]; + + var sql = db.ToInsertStatement(row); + sql.Print(); + db.ExecuteSql(sql); + + var insertedRow = db.SingleById(row.Id); + Assert.That(insertedRow.Equals(row)); + } + } } } \ No newline at end of file From 49f4660b7d9fac4978bfe757b5f69dfa28d0c6d4 Mon Sep 17 00:00:00 2001 From: Darren Reid Date: Wed, 24 Feb 2021 12:31:13 +1100 Subject: [PATCH 3/3] Add additional test for ToInsertAndUpdateStatementTests.cs using `DateTime?` . --- .../Shared/Person.cs | 48 ++++++++++++++++++- .../ToInsertAndUpdateStatementTests.cs | 17 +++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/Person.cs b/tests/ServiceStack.OrmLite.Tests/Shared/Person.cs index 7e4667aff..f80b06bfa 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/Person.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/Person.cs @@ -1,4 +1,5 @@ -using ServiceStack.DataAnnotations; +using System; +using ServiceStack.DataAnnotations; namespace ServiceStack.OrmLite.Tests.Shared { @@ -157,4 +158,49 @@ public override int GetHashCode() } } } + + public class TestProduct + { + public string Id { get; set; } + + public string Name { get; set; } + + public DateTime? Modified { get; set; } + + public static TestProduct[] TestValues = + { + new TestProduct + { + Id = "1", + Modified = null, + Name = "Testing" + } + }; + + protected bool Equals(TestProduct other) + { + return Id == other.Id && + string.Equals(Name, other.Name) && + Modified.Equals(other.Modified); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((TestProduct)obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = (Id != null ? Id.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (Name != null ? Name.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (Modified != null ? Modified.GetHashCode() : 0); + return hashCode; + } + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/ToInsertAndUpdateStatementTests.cs b/tests/ServiceStack.OrmLite.Tests/ToInsertAndUpdateStatementTests.cs index edaeaff7a..b686cc8c4 100644 --- a/tests/ServiceStack.OrmLite.Tests/ToInsertAndUpdateStatementTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/ToInsertAndUpdateStatementTests.cs @@ -79,5 +79,22 @@ public void Correct_Ref_in_ToInsertStatement() Assert.That(insertedRow.Equals(row)); } } + + [Test] + public void Correct_nullable_in_ToInsertStatement() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + var row = TestProduct.TestValues[0]; + + var sql = db.ToInsertStatement(row); + sql.Print(); + db.ExecuteSql(sql); + + var insertedRow = db.SingleById(row.Id); + Assert.AreEqual(insertedRow, row); + } + } } } \ No newline at end of file