From 48e65aafe4322a6fa7906bce33a5fc6b819e5458 Mon Sep 17 00:00:00 2001 From: "F.D.Castel" Date: Mon, 23 Mar 2026 02:10:24 -0300 Subject: [PATCH 1/2] Add tests for Value column quoting in Single/SingleOrDefault queries. Fix #1234. --- .../Query/ElementaryTests.cs | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/Query/ElementaryTests.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/Query/ElementaryTests.cs index 3c73dd6c5..acfdc3ff3 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/Query/ElementaryTests.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/Query/ElementaryTests.cs @@ -209,6 +209,53 @@ public async Task SelectWithCollate() StringAssert.Contains(@"CAST(_UTF8'test' AS VARCHAR(4) CHARACTER SET UTF8) COLLATE UNICODE_CI_AI", sql); } } + + [Test] + public async Task SqlQueryScalarSingleQuotesValueColumn() + { + await using (var db = await GetDbContext()) + { + var result = await db.Database.SqlQueryRaw(@"SELECT 1 AS ""Value"" FROM RDB$DATABASE").SingleAsync(); + var sql = db.LastCommandText; + Assert.AreEqual(1, result); + StringAssert.DoesNotContain("Value", sql.Replace(@"""Value""", string.Empty)); + } + } + + [Test] + public async Task SqlQueryScalarSingleOrDefaultQuotesValueColumn() + { + await using (var db = await GetDbContext()) + { + var result = await db.Database.SqlQueryRaw(@"SELECT 1 AS ""Value"" FROM RDB$DATABASE").SingleOrDefaultAsync(); + var sql = db.LastCommandText; + Assert.AreEqual(1, result); + StringAssert.DoesNotContain("Value", sql.Replace(@"""Value""", string.Empty)); + } + } + + [Test] + public async Task SqlQueryScalarComposedWhereQuotesValueColumn() + { + await using (var db = await GetDbContext()) + { + var query = db.Database.SqlQueryRaw(@"SELECT 1 AS ""Value"" FROM RDB$DATABASE").Where(x => x > 0); + Assert.DoesNotThrowAsync(() => query.LoadAsync()); + var sql = db.LastCommandText; + StringAssert.DoesNotContain("Value", sql.Replace(@"""Value""", string.Empty)); + } + } + + [Test] + public async Task EntitySingleOrDefaultQuotesIdentifiers() + { + await using (var db = await GetDbContext()) + { + var result = await db.Set().OrderBy(x => x.AttachmentId).Take(1).SingleOrDefaultAsync(); + var sql = db.LastCommandText; + Assert.IsNotNull(result); + } + } } class SelectContext : FbTestDbContext From fb7a19c9d868dbed160d467eceba6a6e4feafdfa Mon Sep 17 00:00:00 2001 From: "F.D.Castel" Date: Tue, 24 Mar 2026 15:26:00 -0300 Subject: [PATCH 2/2] Address review: use positive assertions and wrap async calls in Assert.DoesNotThrowAsync --- .../Query/ElementaryTests.cs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/Query/ElementaryTests.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/Query/ElementaryTests.cs index acfdc3ff3..5c756a310 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/Query/ElementaryTests.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/Query/ElementaryTests.cs @@ -215,10 +215,10 @@ public async Task SqlQueryScalarSingleQuotesValueColumn() { await using (var db = await GetDbContext()) { - var result = await db.Database.SqlQueryRaw(@"SELECT 1 AS ""Value"" FROM RDB$DATABASE").SingleAsync(); + var query = db.Database.SqlQueryRaw(@"SELECT 1 AS ""Value"" FROM RDB$DATABASE"); + Assert.DoesNotThrowAsync(() => query.SingleAsync()); var sql = db.LastCommandText; - Assert.AreEqual(1, result); - StringAssert.DoesNotContain("Value", sql.Replace(@"""Value""", string.Empty)); + StringAssert.Contains(@"""Value""", sql); } } @@ -227,10 +227,10 @@ public async Task SqlQueryScalarSingleOrDefaultQuotesValueColumn() { await using (var db = await GetDbContext()) { - var result = await db.Database.SqlQueryRaw(@"SELECT 1 AS ""Value"" FROM RDB$DATABASE").SingleOrDefaultAsync(); + var query = db.Database.SqlQueryRaw(@"SELECT 1 AS ""Value"" FROM RDB$DATABASE"); + Assert.DoesNotThrowAsync(() => query.SingleOrDefaultAsync()); var sql = db.LastCommandText; - Assert.AreEqual(1, result); - StringAssert.DoesNotContain("Value", sql.Replace(@"""Value""", string.Empty)); + StringAssert.Contains(@"""Value""", sql); } } @@ -242,7 +242,7 @@ public async Task SqlQueryScalarComposedWhereQuotesValueColumn() var query = db.Database.SqlQueryRaw(@"SELECT 1 AS ""Value"" FROM RDB$DATABASE").Where(x => x > 0); Assert.DoesNotThrowAsync(() => query.LoadAsync()); var sql = db.LastCommandText; - StringAssert.DoesNotContain("Value", sql.Replace(@"""Value""", string.Empty)); + StringAssert.Contains(@"""Value""", sql); } } @@ -251,9 +251,8 @@ public async Task EntitySingleOrDefaultQuotesIdentifiers() { await using (var db = await GetDbContext()) { - var result = await db.Set().OrderBy(x => x.AttachmentId).Take(1).SingleOrDefaultAsync(); - var sql = db.LastCommandText; - Assert.IsNotNull(result); + var query = db.Set().OrderBy(x => x.AttachmentId).Take(1); + Assert.DoesNotThrowAsync(() => query.SingleOrDefaultAsync()); } } }