diff --git a/src/SQLite.cs b/src/SQLite.cs index f922bcee..ee172b39 100644 --- a/src/SQLite.cs +++ b/src/SQLite.cs @@ -3004,20 +3004,30 @@ public IEnumerable ExecuteDeferredQuery (TableMapping map) var stmt = Prepare (); try { var cols = new TableMapping.Column[SQLite3.ColumnCount (stmt)]; - var fastColumnSetters = new Action[SQLite3.ColumnCount (stmt)]; + var fastColumnSetters = new Action[SQLite3.ColumnCount (stmt)]; if (map.Method == TableMapping.MapMethod.ByPosition) { Array.Copy(map.Columns, cols, Math.Min(cols.Length, map.Columns.Length)); } - else if (map.Method == TableMapping.MapMethod.ByName) - { - for (int i = 0; i < cols.Length; i++) - { + else if (map.Method == TableMapping.MapMethod.ByName) { + MethodInfo getSetter = null; + if (typeof(T) != map.MappedType) { + getSetter = typeof(FastColumnSetter) + .GetMethod (nameof(FastColumnSetter.GetFastSetter), + BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod (map.MappedType); + } + + for (int i = 0; i < cols.Length; i++) { var name = SQLite3.ColumnName16 (stmt, i); cols[i] = map.FindColumn (name); if (cols[i] != null) - fastColumnSetters[i] = FastColumnSetter.GetFastSetter (_conn, cols[i]); + if (getSetter != null) { + fastColumnSetters[i] = (Action)getSetter.Invoke(null, new object[]{ _conn, cols[i]}); + } + else { + fastColumnSetters[i] = FastColumnSetter.GetFastSetter(_conn, cols[i]); + } } } @@ -3028,7 +3038,7 @@ public IEnumerable ExecuteDeferredQuery (TableMapping map) continue; if (fastColumnSetters[i] != null) { - fastColumnSetters[i].Invoke ((T)obj, stmt, i); + fastColumnSetters[i].Invoke (obj, stmt, i); } else { var colType = SQLite3.ColumnType (stmt, i); @@ -3369,9 +3379,9 @@ internal class FastColumnSetter /// /// If no fast setter is available for the requested column (enums in particular cause headache), then this function returns null. /// - internal static Action GetFastSetter (SQLiteConnection conn, TableMapping.Column column) + internal static Action GetFastSetter (SQLiteConnection conn, TableMapping.Column column) { - Action fastSetter = null; + Action fastSetter = null; Type clrType = column.PropertyInfo.PropertyType; @@ -3528,7 +3538,7 @@ internal class FastColumnSetter /// The column mapping that identifies the target member of the destination object /// A lambda that can be used to retrieve the column value at query-time /// A strongly-typed delegate - private static Action CreateNullableTypedSetterDelegate (TableMapping.Column column, Func getColumnValue) where ColumnMemberType : struct + private static Action CreateNullableTypedSetterDelegate (TableMapping.Column column, Func getColumnValue) where ColumnMemberType : struct { var clrTypeInfo = column.PropertyInfo.PropertyType.GetTypeInfo(); bool isNullable = false; @@ -3545,7 +3555,7 @@ internal class FastColumnSetter return (o, stmt, i) => { var colType = SQLite3.ColumnType (stmt, i); if (colType != SQLite3.ColType.Null) - setProperty.Invoke (o, getColumnValue.Invoke (stmt, i)); + setProperty.Invoke ((ObjectType)o, getColumnValue.Invoke (stmt, i)); }; } @@ -3560,7 +3570,7 @@ internal class FastColumnSetter /// The column mapping that identifies the target member of the destination object /// A lambda that can be used to retrieve the column value at query-time /// A strongly-typed delegate - private static Action CreateTypedSetterDelegate (TableMapping.Column column, Func getColumnValue) + private static Action CreateTypedSetterDelegate (TableMapping.Column column, Func getColumnValue) { var setProperty = (Action)Delegate.CreateDelegate ( typeof (Action), null, @@ -3569,7 +3579,7 @@ internal class FastColumnSetter return (o, stmt, i) => { var colType = SQLite3.ColumnType (stmt, i); if (colType != SQLite3.ColType.Null) - setProperty.Invoke (o, getColumnValue.Invoke (stmt, i)); + setProperty.Invoke ((ObjectType)o, getColumnValue.Invoke (stmt, i)); }; } } diff --git a/tests/SQLite.Tests/DbCommandTest.cs b/tests/SQLite.Tests/DbCommandTest.cs new file mode 100644 index 00000000..4d40eeb0 --- /dev/null +++ b/tests/SQLite.Tests/DbCommandTest.cs @@ -0,0 +1,55 @@ +using System.Linq; +using System.Text; +using SQLite; +using System.Threading.Tasks; +using System.IO; + +#if NETFX_CORE +using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; +using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; +using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; +using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; +#else +using NUnit.Framework; +#endif + +namespace SQLite.Tests +{ + [TestFixture] + public class DbCommandTest + { + [Test] + public void QueryCommand() + { + var db = new SQLiteConnection (Path.GetTempFileName(), true); + db.CreateTable(); + var b = new Product(); + db.Insert(b); + + var test = db.CreateCommand("select * from Product") + .ExecuteDeferredQuery(new TableMapping(typeof(Product))).ToList(); + + + Assert.AreEqual (test.Count, 1); + } + + #region Issue #1048 + + [Test] + public void QueryCommandCastToObject() + { + var db = new SQLiteConnection (Path.GetTempFileName(), true); + db.CreateTable(); + var b = new Product(); + db.Insert(b); + + var test = db.CreateCommand("select * from Product") + .ExecuteDeferredQuery(new TableMapping(typeof(Product))).ToList(); + + + Assert.AreEqual (test.Count, 1); + } + + #endregion + } +}