Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit ca4fadc

Browse files
committed
Change how we read numeric values to handle coercions to different number types
1 parent aec47cd commit ca4fadc

File tree

5 files changed

+109
-6
lines changed

5 files changed

+109
-6
lines changed

src/ServiceStack.OrmLite.Oracle.Tests/ServiceStack.OrmLite.Oracle.Tests.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@
198198
<Compile Include="..\..\tests\ServiceStack.OrmLite.Tests\OrmLiteUtilExtensionsTests.cs">
199199
<Link>OrmLiteUtilExtensionsTests.cs</Link>
200200
</Compile>
201+
<Compile Include="..\..\tests\ServiceStack.OrmLite.Tests\PerfTests.cs">
202+
<Link>PerfTests.cs</Link>
203+
</Compile>
201204
<Compile Include="..\..\tests\ServiceStack.OrmLite.Tests\Shared\ApiUtilExtensions.cs">
202205
<Link>Shared\ApiUtilExtensions.cs</Link>
203206
</Compile>

src/ServiceStack.OrmLite/OrmLiteReadExtensions.cs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,35 @@ public static GetValueDelegate GetValueFn<T>(IDataRecord reader)
8181
case TypeCode.Boolean:
8282
return i => reader.GetBoolean(i);
8383
case TypeCode.Int16:
84-
return i => reader.GetInt16(i);
8584
case TypeCode.Int32:
86-
return i => reader.GetInt32(i);
8785
case TypeCode.Int64:
88-
return i => reader.GetInt64(i);
8986
case TypeCode.Single:
90-
return i => reader.GetFloat(i);
9187
case TypeCode.Double:
92-
return i => reader.GetDouble(i);
9388
case TypeCode.Decimal:
94-
return i => reader.GetDecimal(i);
89+
return i =>
90+
{
91+
var value = reader.GetValue(i);
92+
if (value is T)
93+
return value;
94+
95+
switch (typeCode)
96+
{
97+
case TypeCode.Int16:
98+
return Convert.ToInt16(value);
99+
case TypeCode.Int32:
100+
return Convert.ToInt32(value);
101+
case TypeCode.Int64:
102+
return Convert.ToInt16(value);
103+
case TypeCode.Single:
104+
return Convert.ToSingle(value);
105+
case TypeCode.Double:
106+
return Convert.ToDouble(value);
107+
case TypeCode.Decimal:
108+
return Convert.ToDecimal(value);
109+
default:
110+
return value;
111+
}
112+
};
95113
case TypeCode.DateTime:
96114
return i => reader.GetDateTime(i);
97115
}

tests/ServiceStack.OrmLite.Tests/OrmLiteSelectTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Linq;
35
using NUnit.Framework;
46
using ServiceStack.Common;
57
using ServiceStack.Common.Tests.Models;
@@ -364,5 +366,27 @@ public void Can_handle_TimeSpans()
364366
}
365367
}
366368

369+
[Test]
370+
public void Does_return_correct_numeric_values()
371+
{
372+
using (var db = OpenDbConnection())
373+
{
374+
db.DropAndCreateTable<ModelWithDifferentNumTypes>();
375+
376+
var row = ModelWithDifferentNumTypes.Create(1);
377+
378+
db.Insert(row);
379+
380+
var fromDb = db.Select<ModelWithDifferentNumTypes>().First();
381+
382+
Assert.That(row.Short, Is.EqualTo(fromDb.Short));
383+
Assert.That(row.Int, Is.EqualTo(fromDb.Int));
384+
Assert.That(row.Long, Is.EqualTo(fromDb.Long));
385+
Assert.That(row.Float, Is.EqualTo(fromDb.Float));
386+
Assert.That(row.Double, Is.EqualTo(fromDb.Double));
387+
Assert.That(row.Decimal, Is.EqualTo(fromDb.Decimal));
388+
}
389+
}
390+
367391
}
368392
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using System.Diagnostics;
2+
using NUnit.Framework;
3+
using ServiceStack.Common.Tests.Models;
4+
using ServiceStack.DataAnnotations;
5+
using ServiceStack.Text;
6+
7+
namespace ServiceStack.OrmLite.Tests
8+
{
9+
public class ModelWithDifferentNumTypes
10+
{
11+
[AutoIncrement]
12+
public int Id { get; set; }
13+
14+
public short Short { get; set; }
15+
public int Int { get; set; }
16+
public long Long { get; set; }
17+
public float Float { get; set; }
18+
public double Double { get; set; }
19+
public decimal Decimal { get; set; }
20+
21+
public static ModelWithDifferentNumTypes Create(int i)
22+
{
23+
return new ModelWithDifferentNumTypes
24+
{
25+
Short = (short)i,
26+
Int = i,
27+
Long = i,
28+
Float = (float)i * i * .1f,
29+
Double = (double)i * i * .1d,
30+
Decimal = (decimal)i * i * .1m,
31+
};
32+
}
33+
}
34+
35+
[TestFixture, Explicit]
36+
public class PerfTests : OrmLiteTestBase
37+
{
38+
[Test]
39+
public void Is_GetValue_Slow()
40+
{
41+
using (var db = OpenDbConnection())
42+
{
43+
db.DropAndCreateTable<ModelWithDifferentNumTypes>();
44+
45+
100.Times(x =>
46+
db.Insert(ModelWithDifferentNumTypes.Create(x)));
47+
48+
int count = 0;
49+
50+
var sw = Stopwatch.StartNew();
51+
100.Times(i => count += db.Select<ModelWithDifferentNumTypes>().Count);
52+
53+
sw.ElapsedMilliseconds.ToString().Print();
54+
}
55+
}
56+
}
57+
}

tests/ServiceStack.OrmLite.Tests/ServiceStack.OrmLite.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129
<Compile Include="MockAllApiTests.cs" />
130130
<Compile Include="OrmLiteExecFilterTests.cs" />
131131
<Compile Include="OrmLiteFiltersTests.cs" />
132+
<Compile Include="PerfTests.cs" />
132133
<Compile Include="StringSerializerTests.cs" />
133134
<Compile Include="TypeDescriptorMetadataTests.cs" />
134135
<Compile Include="Shared\ApiUtilExtensions.cs" />

0 commit comments

Comments
 (0)