From 26e030a6bc56ccdb7e5a539017022738fe2cb85f Mon Sep 17 00:00:00 2001 From: Adam Schroder Date: Wed, 23 Nov 2016 17:23:13 +1100 Subject: [PATCH] Use GetValues once per row rather than GetValue each per field. --- src/NPoco/RowMappers/PropertyMapper.cs | 24 +++++++++++++----------- test/NPoco.Tests/NewMapper/FakeReader.cs | 10 ++++++++-- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/NPoco/RowMappers/PropertyMapper.cs b/src/NPoco/RowMappers/PropertyMapper.cs index 139feb98..39b50176 100644 --- a/src/NPoco/RowMappers/PropertyMapper.cs +++ b/src/NPoco/RowMappers/PropertyMapper.cs @@ -42,7 +42,9 @@ public override object Map(DbDataReader dataReader, RowMapperContext context) _mappingOntoExistingInstance = true; } - _mapPlan(dataReader, context.Instance); + object[] values = new object[dataReader.FieldCount]; + dataReader.GetValues(values); + _mapPlan(dataReader, values, context.Instance); var result = context.Instance as IOnLoaded; if (result != null) @@ -53,16 +55,16 @@ public override object Map(DbDataReader dataReader, RowMapperContext context) return context.Instance; } - public delegate bool MapPlan(DbDataReader reader, object instance); + public delegate bool MapPlan(DbDataReader dataReader, object[] reader, object instance); private MapPlan BuildMapPlan(DbDataReader dataReader, PocoData pocoData) { var plans = _groupedNames.SelectMany(x => BuildMapPlans(x, dataReader, pocoData, pocoData.Members)).ToArray(); - return (reader, instance) => + return (reader, values, instance) => { foreach (MapPlan plan in plans) { - plan(reader, instance); + plan(reader, values, instance); } return true; }; @@ -89,14 +91,14 @@ private IEnumerable BuildMapPlans(GroupResult groupedName, DbD var subPlans = groupedName.SubItems.SelectMany(x => BuildMapPlans(x, dataReader, pocoData, children)).ToArray(); - yield return (reader, instance) => + yield return (reader, values, instance) => { var newObject = pocoMember.IsList ? pocoMember.Create(dataReader) : (pocoMember.GetValue(instance) ?? pocoMember.Create(dataReader)); var shouldSetNestedObject = false; foreach (var subPlan in subPlans) { - shouldSetNestedObject |= subPlan(reader, newObject); + shouldSetNestedObject |= subPlan(reader, values, newObject); } if (shouldSetNestedObject) @@ -120,7 +122,7 @@ private IEnumerable BuildMapPlans(GroupResult groupedName, DbD var destType = pocoMember.MemberInfoData.MemberType; var defaultValue = MappingHelper.GetDefault(destType); var converter = GetConverter(pocoData, pocoMember.PocoColumn, dataReader.GetFieldType(groupedName.Key.Pos), destType); - yield return (reader, instance) => MapValue(groupedName, reader, converter, instance, pocoMember.PocoColumn, defaultValue); + yield return (reader, values, instance) => MapValue(groupedName, values, converter, instance, pocoMember.PocoColumn, defaultValue); } } @@ -130,12 +132,12 @@ public static bool IsEqual(string name, string value) || string.Equals(value, name.Replace("_", ""), StringComparison.OrdinalIgnoreCase); } - private bool MapValue(GroupResult posName, DbDataReader reader, Func converter, object instance, PocoColumn pocoColumn, object defaultValue) + private bool MapValue(GroupResult posName, object[] values, Func converter, object instance, PocoColumn pocoColumn, object defaultValue) { - if (!reader.IsDBNull(posName.Key.Pos)) + var value = values[posName.Key.Pos]; + if (!Equals(value, DBNull.Value)) { - var value = converter != null ? converter(reader.GetValue(posName.Key.Pos)) : reader.GetValue(posName.Key.Pos); - pocoColumn.SetValue(instance, value); + pocoColumn.SetValue(instance, converter != null ? converter(value) : value); return true; } diff --git a/test/NPoco.Tests/NewMapper/FakeReader.cs b/test/NPoco.Tests/NewMapper/FakeReader.cs index d3507f5b..621518c6 100644 --- a/test/NPoco.Tests/NewMapper/FakeReader.cs +++ b/test/NPoco.Tests/NewMapper/FakeReader.cs @@ -94,7 +94,13 @@ public override string GetName(int i) public override int GetValues(object[] values) { - throw new NotImplementedException(); + values[0] = "Name"; + values[1] = 5; + values[2] = 23m; + values[3] = "AUD"; + values[4] = 24m; + values[5] = "USD"; + return 1; } public override int GetOrdinal(string name) @@ -170,7 +176,7 @@ public override bool IsDBNull(int i) return false; } - public override int FieldCount { get { return 4; } } + public override int FieldCount { get { return 6; } } public override object this[int ordinal] {