Skip to content

Commit 9c696cf

Browse files
committed
fix: 修复 ISqlQuery 聚合函数问题 #45
1 parent cb855bd commit 9c696cf

File tree

5 files changed

+164
-32
lines changed

5 files changed

+164
-32
lines changed

framework/src/Bing.Data.Sql/Bing/Data/Sql/Builders/Clauses/SelectClause.cs

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,7 @@ public SelectClause(ISqlBuilder sqlBuilder, IDialect dialect, IEntityResolver re
8989
/// <typeparam name="TEntity">实体类型</typeparam>
9090
/// <param name="expression">列名表达式</param>
9191
/// <param name="columnAlias">列别名</param>
92-
public void Count<TEntity>(Expression<Func<TEntity, object>> expression, string columnAlias = null) where TEntity : class
93-
{
94-
var column = _resolver.GetColumn(expression);
95-
Count(column, columnAlias);
96-
}
92+
public void Count<TEntity>(Expression<Func<TEntity, object>> expression, string columnAlias = null) where TEntity : class => Aggregate("Count", expression, columnAlias);
9793

9894
/// <summary>
9995
/// 聚合
@@ -118,17 +114,21 @@ public void Count<TEntity>(Expression<Func<TEntity, object>> expression, string
118114
private void Aggregate(string func, string column, string columnAlias) => Aggregate(
119115
$"{func}({_dialect.SafeName(column)})", string.IsNullOrWhiteSpace(columnAlias) ? column : columnAlias);
120116

117+
/// <summary>
118+
/// 聚合
119+
/// </summary>
120+
/// <param name="func">函数名</param>
121+
/// <param name="expression">列名表达式</param>
122+
/// <param name="columnAlias">列别名</param>
123+
private void Aggregate<TEntity>(string func, Expression<Func<TEntity, object>> expression, string columnAlias) => _columns.AddAggregationColumn(func, _resolver.GetColumn(expression), typeof(TEntity), columnAlias);
124+
121125
/// <summary>
122126
/// 求和
123127
/// </summary>
124128
/// <typeparam name="TEntity">实体类型</typeparam>
125129
/// <param name="expression">列名表达式</param>
126130
/// <param name="columnAlias">列别名</param>
127-
public void Sum<TEntity>(Expression<Func<TEntity, object>> expression, string columnAlias = null) where TEntity : class
128-
{
129-
var column = _resolver.GetColumn(expression);
130-
Sum(column, columnAlias);
131-
}
131+
public void Sum<TEntity>(Expression<Func<TEntity, object>> expression, string columnAlias = null) where TEntity : class => Aggregate("Sum", expression, columnAlias);
132132

133133
/// <summary>
134134
/// 求平均值
@@ -143,11 +143,7 @@ public void Sum<TEntity>(Expression<Func<TEntity, object>> expression, string co
143143
/// <typeparam name="TEntity">实体类型</typeparam>
144144
/// <param name="expression">列名表达式</param>
145145
/// <param name="columnAlias">列别名</param>
146-
public void Avg<TEntity>(Expression<Func<TEntity, object>> expression, string columnAlias = null) where TEntity : class
147-
{
148-
var column = _resolver.GetColumn(expression);
149-
Avg(column, columnAlias);
150-
}
146+
public void Avg<TEntity>(Expression<Func<TEntity, object>> expression, string columnAlias = null) where TEntity : class => Aggregate("Avg", expression, columnAlias);
151147

152148
/// <summary>
153149
/// 求最大值
@@ -162,11 +158,7 @@ public void Avg<TEntity>(Expression<Func<TEntity, object>> expression, string co
162158
/// <typeparam name="TEntity">实体类型</typeparam>
163159
/// <param name="expression">列名表达式</param>
164160
/// <param name="columnAlias">列别名</param>
165-
public void Max<TEntity>(Expression<Func<TEntity, object>> expression, string columnAlias = null) where TEntity : class
166-
{
167-
var column = _resolver.GetColumn(expression);
168-
Max(column, columnAlias);
169-
}
161+
public void Max<TEntity>(Expression<Func<TEntity, object>> expression, string columnAlias = null) where TEntity : class => Aggregate("Max", expression, columnAlias);
170162

171163
/// <summary>
172164
/// 求最小值
@@ -181,11 +173,7 @@ public void Max<TEntity>(Expression<Func<TEntity, object>> expression, string co
181173
/// <typeparam name="TEntity">实体类型</typeparam>
182174
/// <param name="expression">列名表达式</param>
183175
/// <param name="columnAlias">列别名</param>
184-
public void Min<TEntity>(Expression<Func<TEntity, object>> expression, string columnAlias = null) where TEntity : class
185-
{
186-
var column = _resolver.GetColumn(expression);
187-
Min(column, columnAlias);
188-
}
176+
public void Min<TEntity>(Expression<Func<TEntity, object>> expression, string columnAlias = null) where TEntity : class => Aggregate("Min", expression, columnAlias);
189177

190178
/// <summary>
191179
/// 设置列名

framework/src/Bing.Data.Sql/Bing/Data/Sql/Builders/Core/ColumnCollection.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,20 @@ public void AddAggregationColumn(string column, string columnAlias)
148148
AddColumn(new ColumnItem(column, columnAlias: columnAlias, isAggregation: true));
149149
}
150150

151+
/// <summary>
152+
/// 添加聚合列
153+
/// </summary>
154+
/// <param name="aggregationFunc">聚合函数</param>
155+
/// <param name="column">列</param>
156+
/// <param name="tableType">表类型</param>
157+
/// <param name="columnAlias">列别名</param>
158+
public void AddAggregationColumn(string aggregationFunc, string column, Type tableType, string columnAlias)
159+
{
160+
if (column.IsEmpty())
161+
return;
162+
AddColumn(new ColumnItem(column, columnAlias: string.IsNullOrEmpty(columnAlias) ? column : columnAlias, isAggregation: true, tableType: tableType, aggregationFunc: aggregationFunc));
163+
}
164+
151165
#endregion
152166

153167
#region RemoveColumns(移除列集合)

framework/src/Bing.Data.Sql/Bing/Data/Sql/Builders/Core/ColumnItem.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ public class ColumnItem
3838
/// </summary>
3939
public bool IsAggregation { get; }
4040

41+
/// <summary>
42+
/// 聚合函数
43+
/// </summary>
44+
public string AggregationFunc { get; }
45+
4146
/// <summary>
4247
/// 初始化一个<see cref="ColumnItem"/>类型的实例
4348
/// </summary>
@@ -47,14 +52,16 @@ public class ColumnItem
4752
/// <param name="tableType">表类型</param>
4853
/// <param name="raw">是否使用原始值</param>
4954
/// <param name="isAggregation">是否聚合函数</param>
50-
public ColumnItem(string name, string tableAlias = null, string columnAlias = null, Type tableType = null, bool raw = false, bool isAggregation = false)
55+
/// <param name="aggregationFunc">聚合函数</param>
56+
public ColumnItem(string name, string tableAlias = null, string columnAlias = null, Type tableType = null, bool raw = false, bool isAggregation = false, string aggregationFunc = null)
5157
{
5258
Name = name;
5359
TableAlias = tableAlias;
5460
ColumnAlias = columnAlias;
5561
TableType = tableType;
5662
Raw = raw;
5763
IsAggregation = isAggregation;
64+
AggregationFunc = aggregationFunc;
5865
}
5966

6067
/// <summary>
@@ -64,9 +71,9 @@ public ColumnItem(string name, string tableAlias = null, string columnAlias = nu
6471
/// <param name="register">实体别名注册器</param>
6572
public string ToSql(IDialect dialect, IEntityAliasRegister register)
6673
{
67-
if (Raw || IsAggregation)
74+
if (Raw || IsAggregation && TableType == null && string.IsNullOrWhiteSpace(AggregationFunc))
6875
return dialect.GetColumn(Name, dialect.GetSafeName(ColumnAlias));
69-
var result = new SqlItem(Name, GetTableAlias(register), ColumnAlias, isResolve: false);
76+
var result = new SqlItem(Name, GetTableAlias(register), ColumnAlias, isResolve: false, aggregationFunc: AggregationFunc);
7077
return result.ToSql(dialect);
7178
}
7279

framework/src/Bing.Data.Sql/Bing/Data/Sql/Builders/Core/SqlItem.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ public class SqlItem
5858
/// </summary>
5959
public string DatabaseName { get; private set; }
6060

61+
/// <summary>
62+
/// 聚合函数
63+
/// </summary>
64+
public string AggregationFunc { get; private set; }
65+
6166
#endregion
6267

6368
#region 构造函数
@@ -71,13 +76,15 @@ public class SqlItem
7176
/// <param name="raw">是否使用原始值</param>
7277
/// <param name="isSplit">是否用句点分割名称</param>
7378
/// <param name="isResolve">是否解析名称</param>
74-
public SqlItem(string name, string prefix = null, string alias = null, bool raw = false, bool isSplit = true, bool isResolve = true)
79+
/// <param name="aggregationFunc">聚合函数</param>
80+
public SqlItem(string name, string prefix = null, string alias = null, bool raw = false, bool isSplit = true, bool isResolve = true, string aggregationFunc = null)
7581
{
7682
if (string.IsNullOrWhiteSpace(name))
7783
return;
7884
_prefix = prefix;
7985
_alias = alias;
8086
Raw = raw;
87+
AggregationFunc = aggregationFunc;
8188
if (raw)
8289
{
8390
_name = name;
@@ -159,7 +166,9 @@ public virtual string ToSql(IDialect dialect = null, ITableDatabase tableDatabas
159166
return null;
160167
if (Raw)
161168
return Name;
162-
var column = GetColumn(dialect, tableDatabase);
169+
var column = string.IsNullOrWhiteSpace(AggregationFunc)
170+
? GetColumn(dialect, tableDatabase)
171+
: $"{AggregationFunc}({GetColumn(dialect, tableDatabase)})";
163172
var columnAlias = GetSafeName(dialect, Alias);
164173
return dialect.GetColumn(column, columnAlias);
165174
}

framework/tests/Bing.Datas.Test.Integration/Sql/Builders/SqlServer/SqlServerBuilderTest.Select.cs

Lines changed: 116 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public void Test_Distinct()
3434
/// <summary>
3535
/// 求总行数
3636
/// </summary>
37-
[Fact(DisplayName = "求总行数")]
37+
[Fact]
3838
public void Test_Count_1()
3939
{
4040
//结果
@@ -51,7 +51,7 @@ public void Test_Count_1()
5151
}
5252

5353
/// <summary>
54-
/// 求总行数 - 加列别名
54+
/// 求总行数 - lambda表达式
5555
/// </summary>
5656
[Fact]
5757
public void Test_Count_2()
@@ -69,6 +69,44 @@ public void Test_Count_2()
6969
Assert.Equal(result.ToString(), _builder.ToSql());
7070
}
7171

72+
/// <summary>
73+
/// 求总行数 - lambda表达式 - 默认别名
74+
/// </summary>
75+
[Fact]
76+
public void Test_Count_3()
77+
{
78+
//结果
79+
var result = new Str();
80+
result.AppendLine("Select Count([DoubleValue]) As [DoubleValue] ");
81+
result.Append("From [b]");
82+
83+
//执行
84+
_builder.Count<Sample>(t => t.DoubleValue)
85+
.From("b");
86+
87+
//验证
88+
Assert.Equal(result.ToString(), _builder.ToSql());
89+
}
90+
91+
/// <summary>
92+
/// 求总行数 - lambda表达式 - 表前缀
93+
/// </summary>
94+
[Fact]
95+
public void Test_Count_4()
96+
{
97+
//结果
98+
var result = new Str();
99+
result.AppendLine("Select Count([b].[DoubleValue]) As [a] ");
100+
result.Append("From [Sample] As [b]");
101+
102+
//执行
103+
_builder.Count<Sample>(t => t.DoubleValue, "a")
104+
.From<Sample>("b");
105+
106+
//验证
107+
Assert.Equal(result.ToString(), _builder.ToSql());
108+
}
109+
72110
/// <summary>
73111
/// 求和
74112
/// </summary>
@@ -126,6 +164,25 @@ public void Test_Sum_3()
126164
Assert.Equal(result.ToString(), _builder.ToSql());
127165
}
128166

167+
/// <summary>
168+
/// 求和 - lambda表达式 - 表前缀
169+
/// </summary>
170+
[Fact]
171+
public void Test_Sum_4()
172+
{
173+
//结果
174+
var result = new Str();
175+
result.AppendLine("Select Sum([b].[DoubleValue]) As [a] ");
176+
result.Append("From [Sample] As [b]");
177+
178+
//执行
179+
_builder.Sum<Sample>(t => t.DoubleValue, "a")
180+
.From<Sample>("b");
181+
182+
//验证
183+
Assert.Equal(result.ToString(), _builder.ToSql());
184+
}
185+
129186
/// <summary>
130187
/// 求平均值
131188
/// </summary>
@@ -183,6 +240,25 @@ public void Test_Avg_3()
183240
Assert.Equal(result.ToString(), _builder.ToSql());
184241
}
185242

243+
/// <summary>
244+
/// 求平均值 - lambda表达式 - 表前缀
245+
/// </summary>
246+
[Fact]
247+
public void Test_Avg_4()
248+
{
249+
//结果
250+
var result = new Str();
251+
result.AppendLine("Select Avg([b].[DoubleValue]) As [a] ");
252+
result.Append("From [Sample] As [b]");
253+
254+
//执行
255+
_builder.Avg<Sample>(t => t.DoubleValue, "a")
256+
.From<Sample>("b");
257+
258+
//验证
259+
Assert.Equal(result.ToString(), _builder.ToSql());
260+
}
261+
186262
/// <summary>
187263
/// 求最大值
188264
/// </summary>
@@ -240,6 +316,25 @@ public void Test_Max_3()
240316
Assert.Equal(result.ToString(), _builder.ToSql());
241317
}
242318

319+
/// <summary>
320+
/// 求最大值 - lambda表达式 - 表前缀
321+
/// </summary>
322+
[Fact]
323+
public void Test_Max_4()
324+
{
325+
//结果
326+
var result = new Str();
327+
result.AppendLine("Select Max([b].[DoubleValue]) As [a] ");
328+
result.Append("From [Sample] As [b]");
329+
330+
//执行
331+
_builder.Max<Sample>(t => t.DoubleValue, "a")
332+
.From<Sample>("b");
333+
334+
//验证
335+
Assert.Equal(result.ToString(), _builder.ToSql());
336+
}
337+
243338
/// <summary>
244339
/// 求最小值
245340
/// </summary>
@@ -297,6 +392,25 @@ public void Test_Min_3()
297392
Assert.Equal(result.ToString(), _builder.ToSql());
298393
}
299394

395+
/// <summary>
396+
/// 求最小值 - lambda表达式 - 表前缀
397+
/// </summary>
398+
[Fact]
399+
public void Test_Min_4()
400+
{
401+
//结果
402+
var result = new Str();
403+
result.AppendLine("Select Min([b].[DoubleValue]) As [a] ");
404+
result.Append("From [Sample] As [b]");
405+
406+
//执行
407+
_builder.Min<Sample>(t => t.DoubleValue, "a")
408+
.From<Sample>("b");
409+
410+
//验证
411+
Assert.Equal(result.ToString(), _builder.ToSql());
412+
}
413+
300414
/// <summary>
301415
/// 设置列
302416
/// </summary>

0 commit comments

Comments
 (0)