Skip to content

Commit 5593fc5

Browse files
support includes
1 parent 71f2210 commit 5593fc5

File tree

5 files changed

+102
-12
lines changed

5 files changed

+102
-12
lines changed

Program/Program.cs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,25 @@ static void Main(string[] args)
3939

4040
// SQLiteConnection.CreateFile("Demo.db");
4141

42-
connection = new SQLiteConnection("Data Source=Demo.db");
42+
// connection = new SQLiteConnection("Data Source=Demo.db");
4343

44-
var db = new QueryFactory(connection, new SqliteCompiler());
44+
var db = new QueryFactory(connection, new SqlServerCompiler());
4545

46-
// db.Statement("create table accounts(id integer primary key,name text,currency_id text);");
46+
db.Logger = result =>
47+
{
48+
Console.WriteLine(result.ToString());
49+
};
4750

48-
db.Logger = q => Console.WriteLine(q.ToString());
51+
var accounts = db.Query("Accounts")
52+
.WhereNotNull("BankId")
53+
.Include("bank",
54+
db.Query("Banks").Include("Country", db.Query("Countries"))
55+
.Select("Id", "Name", "CountryId")
56+
)
57+
.Select("Id", "Name", "BankId")
58+
.OrderByDesc("Id").Limit(10).Get();
4959

50-
var accounts = db.Query("Accounts").OrderByDesc("Id").Offset(10).Get();
51-
52-
Console.WriteLine(JsonConvert.SerializeObject(accounts));
60+
Console.WriteLine(JsonConvert.SerializeObject(accounts, Formatting.Indented));
5361

5462
}
5563

QueryBuilder/Include.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace SqlKata
2+
{
3+
public class Include
4+
{
5+
public string Name { get; set; }
6+
public Query Query { get; set; }
7+
public string ForeignKey { get; set; }
8+
public string LocalKey { get; set; }
9+
}
10+
}

QueryBuilder/Query.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public partial class Query : BaseQuery<Query>
1010
public string QueryAlias { get; set; }
1111
public string Method { get; set; } = "select";
1212
public string QueryComment { get; set; }
13+
public List<Include> Includes = new List<Include>();
1314

1415
public Query() : base()
1516
{
@@ -56,6 +57,7 @@ public override Query Clone()
5657
clone.QueryAlias = QueryAlias;
5758
clone.IsDistinct = IsDistinct;
5859
clone.Method = Method;
60+
clone.Includes = Includes;
5961
return clone;
6062
}
6163

@@ -308,5 +310,23 @@ public override Query NewQuery()
308310
return new Query();
309311
}
310312

313+
public Query Include(string relationName, Query query, string foreignKey = null, string localKey = "Id")
314+
{
315+
if (foreignKey == null)
316+
{
317+
foreignKey = relationName + "Id";
318+
}
319+
320+
Includes.Add(new Include
321+
{
322+
Name = relationName,
323+
LocalKey = localKey,
324+
ForeignKey = foreignKey,
325+
Query = query,
326+
});
327+
328+
return this;
329+
}
330+
311331
}
312332
}

SqlKata.Execution/QueryFactory.Extensions.cs

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Data;
4+
using System.Dynamic;
45
using System.Linq;
56
using Dapper;
67

@@ -14,11 +15,52 @@ public static IEnumerable<T> Get<T>(this QueryFactory db, Query query)
1415
{
1516
var compiled = db.Compile(query);
1617

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

2466
public static IEnumerable<IDictionary<string, object>> GetDictionary(this QueryFactory db, Query query)
@@ -30,7 +72,7 @@ public static IEnumerable<IDictionary<string, object>> GetDictionary(this QueryF
3072

3173
public static IEnumerable<dynamic> Get(this QueryFactory db, Query query)
3274
{
33-
return Get<dynamic>(db, query);
75+
return Get<dynamic>(db, query).Cast<IDictionary<string, object>>().ToList();
3476
}
3577

3678
public static T First<T>(this QueryFactory db, Query query)
@@ -42,7 +84,14 @@ public static T First<T>(this QueryFactory db, Query query)
4284

4385
public static dynamic First(this QueryFactory db, Query query)
4486
{
45-
return First<dynamic>(db, query);
87+
var list = Get<dynamic>(db, query);
88+
89+
if (!list.Any())
90+
{
91+
throw new InvalidOperationException("The sequence contains no elements");
92+
}
93+
94+
return list.ElementAt(0);
4695
}
4796

4897
public static T FirstOrDefault<T>(this QueryFactory db, Query query)
@@ -54,7 +103,9 @@ public static T FirstOrDefault<T>(this QueryFactory db, Query query)
54103

55104
public static dynamic FirstOrDefault(this QueryFactory db, Query query)
56105
{
57-
return FirstOrDefault<dynamic>(db, query);
106+
var list = Get<dynamic>(db, query);
107+
108+
return list.Any() ? list.ElementAt(0) : null;
58109
}
59110

60111
public static int Execute(

SqlKata.Execution/QueryFactory.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public Query FromQuery(Query query)
5252
xQuery.QueryAlias = query.QueryAlias;
5353
xQuery.IsDistinct = query.IsDistinct;
5454
xQuery.Method = query.Method;
55+
xQuery.Includes = query.Includes;
5556

5657
xQuery.SetEngineScope(query.EngineScope);
5758

0 commit comments

Comments
 (0)