Skip to content

Commit 8bd6f8e

Browse files
committed
#253 Support for subqueries
1 parent 52dbe35 commit 8bd6f8e

File tree

5 files changed

+70
-3
lines changed

5 files changed

+70
-3
lines changed

src/QueryBuilderByLinq/SelectQueryBuilder.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,14 @@ private SelectQuery BuildAsRoot(MethodCallExpression expression)
108108
{
109109
if (from.Value is IQueryable q && q.Provider is TableQuery tq)
110110
{
111-
sq.From(tq.TableName).As(fromAlias.Name!);
111+
if (tq.InnerQuery != null)
112+
{
113+
sq.From(tq.InnerQuery.ToQueryAsPostgres()).As(fromAlias.Name!);
114+
}
115+
else
116+
{
117+
sq.From(tq.TableName).As(fromAlias.Name!);
118+
}
112119
}
113120
else
114121
{

src/QueryBuilderByLinq/Sql.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ public static IQueryable<T> From<T>(string tableName)
2626
return new Table<T>(tableName);
2727
}
2828

29+
public static IQueryable<T> From<T>(IQueryable<T> subquery)
30+
{
31+
return new Table<T>(subquery);
32+
}
33+
2934
public static IQueryable<T> InnerJoin<T>(Expression<Predicate<T>> condition)
3035
{
3136
return new Table<T>();

src/QueryBuilderByLinq/Table.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections;
1+
using Carbunql.Clauses;
2+
using System.Collections;
23
using System.Linq.Expressions;
34

45
namespace QueryBuilderByLinq;
@@ -15,6 +16,11 @@ public Table(string tableName)
1516
Query = new TableQuery<T>() { TableName = tableName };
1617
}
1718

19+
public Table(IQueryable<T> subquery)
20+
{
21+
Query = new TableQuery<T>() { InnerQuery = subquery.AsQueryable() };
22+
}
23+
1824
private IQueryable<T> Query { get; set; }
1925

2026
public Type ElementType => Query.ElementType;

src/QueryBuilderByLinq/TableQuery.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ namespace QueryBuilderByLinq;
55

66
public abstract class TableQuery
77
{
8-
public string TableName { get; set; } = string.Empty;
8+
public string TableName { get; internal set; } = string.Empty;
9+
10+
public IQueryable? InnerQuery { get; internal set; }
911
}
1012

1113
public class TableQuery<T> : TableQuery, IOrderedQueryable<T>, IQueryProvider
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using Carbunql;
2+
using Xunit.Abstractions;
3+
using static QueryBuilderByLinq.Sql;
4+
5+
namespace QueryBuilderByLinq.Test;
6+
7+
public class SubQueryTest
8+
{
9+
private readonly QueryCommandMonitor Monitor;
10+
11+
public SubQueryTest(ITestOutputHelper output)
12+
{
13+
Monitor = new QueryCommandMonitor(output);
14+
Output = output;
15+
}
16+
17+
private ITestOutputHelper Output { get; set; }
18+
19+
[Fact]
20+
public void DefaultTest()
21+
{
22+
var subq = from a in From<table_a>() select new { ID = a.a_id, Text = a.text };
23+
var query = from x in From(subq) select new { x.ID, x.Text };
24+
25+
var sq = query.ToQueryAsPostgres();
26+
27+
Monitor.Log(sq);
28+
29+
var sql = @"
30+
SELECT
31+
x.ID,
32+
x.Text
33+
FROM
34+
(
35+
SELECT
36+
a.a_id AS ID,
37+
a.text AS Text
38+
FROM
39+
table_a AS a
40+
) AS x";
41+
42+
Assert.Equal(29, sq.GetTokens().ToList().Count);
43+
Assert.Equal(sql.ToValidateText(), sq.ToText().ToValidateText());
44+
}
45+
46+
public record struct table_a(int a_id, string text, int value);
47+
}

0 commit comments

Comments
 (0)