diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteDataReader.cs b/src/Microsoft.Data.Sqlite.Core/SqliteDataReader.cs
index 729b8810755..14f5b60a4eb 100644
--- a/src/Microsoft.Data.Sqlite.Core/SqliteDataReader.cs
+++ b/src/Microsoft.Data.Sqlite.Core/SqliteDataReader.cs
@@ -90,8 +90,9 @@ public override int RecordsAffected
///
/// Gets the value of the specified column.
///
- /// The name of the column. The value is case-sensitive.
+ /// The name of the column.
/// The value.
+ /// Performs a case-sensitive lookup first. If it fails, a second, case-insensitive search occurs.
/// Data Types
public override object this[string name]
=> _record == null
diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteDataRecord.cs b/src/Microsoft.Data.Sqlite.Core/SqliteDataRecord.cs
index 20e54f3980d..d9d78baefee 100644
--- a/src/Microsoft.Data.Sqlite.Core/SqliteDataRecord.cs
+++ b/src/Microsoft.Data.Sqlite.Core/SqliteDataRecord.cs
@@ -133,6 +133,13 @@ public virtual int GetOrdinal(string name)
return ordinal;
}
+ var insensitiveMatchingColumns = _columnNameOrdinalCache.Where(kv => kv.Key.Equals(name, StringComparison.OrdinalIgnoreCase));
+ if(insensitiveMatchingColumns.Count() == 1) {
+ ordinal = insensitiveMatchingColumns.First().Value;
+ _columnNameOrdinalCache.Add(name, ordinal);
+ return ordinal;
+ }
+
// NB: Message is provided by framework
throw new ArgumentOutOfRangeException(nameof(name), name, message: null);
}
diff --git a/test/Microsoft.Data.Sqlite.Tests/SqliteDataReaderTest.cs b/test/Microsoft.Data.Sqlite.Tests/SqliteDataReaderTest.cs
index 59534c302b4..8150c3ffd30 100644
--- a/test/Microsoft.Data.Sqlite.Tests/SqliteDataReaderTest.cs
+++ b/test/Microsoft.Data.Sqlite.Tests/SqliteDataReaderTest.cs
@@ -1276,19 +1276,21 @@ public void GetOrdinal_works()
}
}
- [Fact]
- public void GetOrdinal_throws_when_out_of_range()
+ [Theory]
+ [InlineData("SELECT 1;", "Name")]
+ [InlineData("SELECT 1 as Id, 2 as ID;", "id")]
+ public void GetOrdinal_throws_when_out_of_range(string query, string columnName)
{
using (var connection = new SqliteConnection("Data Source=:memory:"))
{
connection.Open();
- using (var reader = connection.ExecuteReader("SELECT 1;"))
+ using (var reader = connection.ExecuteReader(query))
{
- var ex = Assert.Throws(() => reader.GetOrdinal("Name"));
+ var ex = Assert.Throws(() => reader.GetOrdinal(columnName));
Assert.NotNull(ex.Message);
Assert.Equal("name", ex.ParamName);
- Assert.Equal("Name", ex.ActualValue);
+ Assert.Equal(columnName, ex.ActualValue);
}
}
}
@@ -1583,19 +1585,22 @@ public void Item_by_ordinal_throws_when_non_query()
}
}
- [Fact]
- public void Item_by_name_works()
+ [Theory]
+ [InlineData("SELECT 1 as Id;", "Id", 1L)]
+ [InlineData("SELECT 1 as Id;", "id", 1L)]
+ [InlineData("SELECT 1 as Id, 2 as id;", "id", 2L)]
+ public void Item_by_name_works(string query, string column, long expected)
{
using (var connection = new SqliteConnection("Data Source=:memory:"))
{
connection.Open();
- using (var reader = connection.ExecuteReader("SELECT 1 AS Id;"))
+ using (var reader = connection.ExecuteReader(query))
{
var hasData = reader.Read();
Assert.True(hasData);
- Assert.Equal(1L, reader["Id"]);
+ Assert.Equal(expected, reader[column]);
}
}
}