Skip to content

Commit 490b5d0

Browse files
Merge pull request #233 from sqlkata/includes
Include with async support
2 parents 9737010 + b444d6e commit 490b5d0

File tree

2 files changed

+74
-38
lines changed

2 files changed

+74
-38
lines changed

SqlKata.Execution/QueryFactory.Extensions.Async.cs

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq;
55
using Dapper;
66
using System.Threading.Tasks;
7+
using System.Dynamic;
78

89
namespace SqlKata.Execution
910
{
@@ -15,11 +16,52 @@ public static async Task<IEnumerable<T>> GetAsync<T>(this QueryFactory db, Query
1516
{
1617
var compiled = db.Compile(query);
1718

18-
return await db.Connection.QueryAsync<T>(
19+
var result = (await db.Connection.QueryAsync<T>(
1920
compiled.Sql,
2021
compiled.NamedBindings,
2122
commandTimeout: db.QueryTimeout
22-
);
23+
)).ToList();
24+
25+
if (!result.Any())
26+
{
27+
return result;
28+
}
29+
30+
if (result[0] is IDynamicMetaObjectProvider)
31+
{
32+
var dynamicResult = result
33+
.Cast<IDictionary<string, object>>()
34+
.Select(x => new Dictionary<string, object>(x, StringComparer.OrdinalIgnoreCase))
35+
.ToList();
36+
37+
foreach (var include in query.Includes)
38+
{
39+
var ids = dynamicResult.Where(x => x[include.ForeignKey] != null)
40+
.Select(x => x[include.ForeignKey].ToString())
41+
.ToList();
42+
43+
if (!ids.Any())
44+
{
45+
continue;
46+
}
47+
48+
var related = (await include.Query.WhereIn(include.LocalKey, ids).GetAsync())
49+
.Cast<IDictionary<string, object>>()
50+
.Select(x => new Dictionary<string, object>(x, StringComparer.OrdinalIgnoreCase))
51+
.ToDictionary(x => x[include.LocalKey].ToString());
52+
53+
foreach (var item in dynamicResult)
54+
{
55+
var foreignValue = item[include.ForeignKey].ToString();
56+
item[include.Name] = related.ContainsKey(foreignValue) ? related[foreignValue] : null;
57+
}
58+
}
59+
60+
return dynamicResult.Cast<T>();
61+
62+
}
63+
64+
return result;
2365
}
2466

2567
public static async Task<IEnumerable<IDictionary<string, object>>> GetDictionaryAsync(this QueryFactory db, Query query)
@@ -40,36 +82,33 @@ public static async Task<IEnumerable<dynamic>> GetAsync(this QueryFactory db, Qu
4082
return await GetAsync<dynamic>(db, query);
4183
}
4284

43-
public static async Task<T> FirstAsync<T>(this QueryFactory db, Query query)
85+
public static async Task<T> FirstOrDefaultAsync<T>(this QueryFactory db, Query query)
4486
{
45-
var compiled = db.Compile(query.Limit(1));
87+
var list = await GetAsync<T>(db, query.Limit(1));
4688

47-
return await db.Connection.QueryFirstAsync<T>(
48-
compiled.Sql,
49-
compiled.NamedBindings,
50-
commandTimeout: db.QueryTimeout
51-
);
89+
return list.ElementAtOrDefault(0);
5290
}
5391

54-
public static async Task<dynamic> FirstAsync(this QueryFactory db, Query query)
92+
public static async Task<dynamic> FirstOrDefaultAsync(this QueryFactory db, Query query)
5593
{
56-
return await FirstAsync<dynamic>(db, query);
94+
return await FirstOrDefaultAsync<dynamic>(db, query);
5795
}
5896

59-
public static async Task<T> FirstOrDefaultAsync<T>(this QueryFactory db, Query query)
97+
public static async Task<T> FirstAsync<T>(this QueryFactory db, Query query)
6098
{
61-
var compiled = db.Compile(query.Limit(1));
99+
var item = await FirstOrDefaultAsync<T>(db, query);
62100

63-
return await db.Connection.QueryFirstOrDefaultAsync<T>(
64-
compiled.Sql,
65-
compiled.NamedBindings,
66-
commandTimeout: db.QueryTimeout
67-
);
101+
if (item == null)
102+
{
103+
throw new InvalidOperationException("The sequence contains no elements");
104+
}
105+
106+
return item;
68107
}
69108

70-
public static async Task<dynamic> FirstOrDefaultAsync(this QueryFactory db, Query query)
109+
public static async Task<dynamic> FirstAsync(this QueryFactory db, Query query)
71110
{
72-
return await FirstOrDefaultAsync<dynamic>(db, query);
111+
return await FirstAsync<dynamic>(db, query);
73112
}
74113

75114
public static async Task<int> ExecuteAsync(

SqlKata.Execution/QueryFactory.Extensions.cs

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -72,41 +72,38 @@ public static IEnumerable<IDictionary<string, object>> GetDictionary(this QueryF
7272

7373
public static IEnumerable<dynamic> Get(this QueryFactory db, Query query)
7474
{
75-
return Get<dynamic>(db, query).Cast<IDictionary<string, object>>().ToList();
75+
return Get<dynamic>(db, query);
7676
}
7777

78-
public static T First<T>(this QueryFactory db, Query query)
78+
public static T FirstOrDefault<T>(this QueryFactory db, Query query)
7979
{
80-
var compiled = db.Compile(query.Limit(1));
80+
var list = Get<T>(db, query.Limit(1));
8181

82-
return db.Connection.QueryFirst<T>(compiled.Sql, compiled.NamedBindings, commandTimeout: db.QueryTimeout);
82+
return list.ElementAtOrDefault(0);
8383
}
8484

85-
public static dynamic First(this QueryFactory db, Query query)
85+
public static dynamic FirstOrDefault(this QueryFactory db, Query query)
86+
{
87+
return FirstOrDefault<dynamic>(db, query);
88+
}
89+
90+
public static T First<T>(this QueryFactory db, Query query)
8691
{
87-
var list = Get<dynamic>(db, query);
92+
var item = FirstOrDefault<T>(db, query);
8893

89-
if (!list.Any())
94+
if (item == null)
9095
{
9196
throw new InvalidOperationException("The sequence contains no elements");
9297
}
9398

94-
return list.ElementAt(0);
99+
return item;
95100
}
96101

97-
public static T FirstOrDefault<T>(this QueryFactory db, Query query)
102+
public static dynamic First(this QueryFactory db, Query query)
98103
{
99-
var compiled = db.Compile(query.Limit(1));
100-
101-
return db.Connection.QueryFirstOrDefault<T>(compiled.Sql, compiled.NamedBindings, commandTimeout: db.QueryTimeout);
104+
return First<dynamic>(db, query);
102105
}
103106

104-
public static dynamic FirstOrDefault(this QueryFactory db, Query query)
105-
{
106-
var list = Get<dynamic>(db, query);
107-
108-
return list.Any() ? list.ElementAt(0) : null;
109-
}
110107

111108
public static int Execute(
112109
this QueryFactory db,

0 commit comments

Comments
 (0)