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

Commit ba544c4

Browse files
committed
Add support for async ValueTuple
1 parent f021be5 commit ba544c4

File tree

3 files changed

+65
-8
lines changed

3 files changed

+65
-8
lines changed

src/ServiceStack.OrmLite/Async/OrmLiteUtilExtensionsAsync.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ public static T CreateInstance<T>()
2222

2323
public static Task<T> ConvertToAsync<T>(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, CancellationToken token)
2424
{
25-
var indexCache = reader.GetIndexFieldsCache(ModelDefinition<T>.Definition, dialectProvider);
2625
return dialectProvider.ReaderRead(reader, () =>
2726
{
2827
if (typeof(T) == typeof(List<object>))
@@ -33,10 +32,11 @@ public static Task<T> ConvertToAsync<T>(this IDataReader reader, IOrmLiteDialect
3332

3433
var values = new object[reader.FieldCount];
3534

36-
if (typeof(T).Name.StartsWith("ValueTuple`"))
35+
if (typeof(T).IsValueTuple())
3736
return reader.ConvertToValueTuple<T>(values, dialectProvider);
3837

3938
var row = CreateInstance<T>();
39+
var indexCache = reader.GetIndexFieldsCache(ModelDefinition<T>.Definition, dialectProvider);
4040
row.PopulateWithSqlReader(dialectProvider, reader, indexCache, values);
4141
return row;
4242
}, token).Then(t => {
@@ -51,8 +51,9 @@ public static Task<List<T>> ConvertToListAsync<T>(this IDataReader reader, IOrmL
5151
var isObjectList = typeof(T) == typeof(List<object>);
5252
var isObjectDict = typeof(T) == typeof(Dictionary<string,object>);
5353
var isDynamic = typeof(T) == typeof(object);
54-
var isTuple = typeof(T).Name.StartsWith("Tuple`");
55-
var indexCache = isObjectDict || isObjectDict || isTuple
54+
var isValueTuple = typeof(T).IsValueTuple();
55+
var isTuple = typeof(T).IsTuple();
56+
var indexCache = isObjectDict || isObjectDict || isValueTuple || isTuple
5657
? null
5758
: reader.GetIndexFieldsCache(ModelDefinition<T>.Definition, dialectProvider, onlyFields);
5859

@@ -93,6 +94,11 @@ public static Task<List<T>> ConvertToListAsync<T>(this IDataReader reader, IOrmL
9394
}
9495
return (T)(object)row;
9596
}
97+
if (isValueTuple)
98+
{
99+
var row = reader.ConvertToValueTuple<T>(values, dialectProvider);
100+
return (T)row;
101+
}
96102
if (isTuple)
97103
{
98104
var tupleArgs = reader.ToMultiTuple(dialectProvider, modelIndexCaches, genericArgs, values);

src/ServiceStack.OrmLite/OrmLiteUtils.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,13 @@ public static T CreateInstance<T>()
8181
return (T)ReflectionExtensions.CreateInstance<T>();
8282
}
8383

84+
internal static bool IsTuple(this Type type) => type.Name.StartsWith("Tuple`", StringComparison.Ordinal);
85+
86+
internal static bool IsValueTuple(this Type type) => type.Name.StartsWith("ValueTuple`", StringComparison.Ordinal);
87+
8488
public static bool IsScalar<T>()
8589
{
86-
var isScalar = typeof(T).IsValueType && !typeof(T).Name.StartsWith("ValueTuple`", StringComparison.Ordinal) || typeof(T) == typeof(string);
90+
var isScalar = typeof(T).IsValueType && !typeof(T).IsValueTuple() || typeof(T) == typeof(string);
8791
return isScalar;
8892
}
8993

@@ -101,7 +105,7 @@ public static T ConvertTo<T>(this IDataReader reader, IOrmLiteDialectProvider di
101105

102106
var values = new object[reader.FieldCount];
103107

104-
if (typeof(T).Name.StartsWith("ValueTuple`"))
108+
if (typeof(T).IsValueTuple())
105109
return reader.ConvertToValueTuple<T>(values, dialectProvider);
106110

107111
var row = CreateInstance<T>();
@@ -222,7 +226,7 @@ public static List<T> ConvertToList<T>(this IDataReader reader, IOrmLiteDialectP
222226
}
223227
return (List<T>)(object)to.ToList();
224228
}
225-
if (typeof(T).Name.StartsWith("ValueTuple`", StringComparison.Ordinal))
229+
if (typeof(T).IsValueTuple())
226230
{
227231
var to = new List<T>();
228232
var values = new object[reader.FieldCount];
@@ -236,7 +240,7 @@ public static List<T> ConvertToList<T>(this IDataReader reader, IOrmLiteDialectP
236240
}
237241
return to;
238242
}
239-
if (typeof(T).Name.StartsWith("Tuple`", StringComparison.Ordinal))
243+
if (typeof(T).IsTuple())
240244
{
241245
var to = new List<T>();
242246
using (reader)

tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionTests.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,53 @@ public void Can_Select_as_List_ValueTuple()
200200
}
201201
}
202202

203+
[Test]
204+
public async System.Threading.Tasks.Task Can_Select_as_List_ValueTuple_Async()
205+
{
206+
using (var db = OpenDbConnection())
207+
{
208+
InitLetters(db);
209+
GetIdStats(db);
210+
211+
//var a = new ValueTuple<int, int, int, int>();
212+
//a.Item1 = 1;
213+
214+
var query = db.From<LetterFrequency>()
215+
.Select("COUNT(*), MIN(Letter), MAX(Letter), Sum(Id)");
216+
217+
var results = await db.SelectAsync<(int count, string min, string max, int sum)>(query);
218+
219+
Assert.That(results.Count, Is.EqualTo(1));
220+
221+
var result = results[0];
222+
Assert.That(result.count, Is.EqualTo(10));
223+
Assert.That(result.min, Is.EqualTo("A"));
224+
Assert.That(result.max, Is.EqualTo("D"));
225+
Assert.That(result.sum, Is.EqualTo(letterFrequencySumId));
226+
227+
var single = await db.SingleAsync<(int count, string min, string max, int sum)>(query);
228+
Assert.That(single.count, Is.EqualTo(10));
229+
Assert.That(single.min, Is.EqualTo("A"));
230+
Assert.That(single.max, Is.EqualTo("D"));
231+
Assert.That(single.sum, Is.EqualTo(letterFrequencySumId));
232+
233+
single = await db.SingleAsync<(int count, string min, string max, int sum)>(
234+
db.From<LetterFrequency>()
235+
.Select(x => new
236+
{
237+
Count = Sql.Count("*"),
238+
Min = Sql.Min(x.Letter),
239+
Max = Sql.Max(x.Letter),
240+
Sum = Sql.Sum(x.Id)
241+
}));
242+
243+
Assert.That(single.count, Is.EqualTo(10));
244+
Assert.That(single.min, Is.EqualTo("A"));
245+
Assert.That(single.max, Is.EqualTo("D"));
246+
Assert.That(single.sum, Is.EqualTo(letterFrequencySumId));
247+
}
248+
}
249+
203250
private void CheckDbTypeInsensitiveEquivalency(List<object> result)
204251
{
205252
Assert.That(Convert.ToInt64(result[0]), Is.EqualTo(10));

0 commit comments

Comments
 (0)