2
2
using System ;
3
3
using System . Collections . Generic ;
4
4
using System . Data ;
5
- using System . Data . SqlClient ;
6
5
using System . Linq ;
6
+ using System . Text ;
7
7
using System . Web . Helpers ;
8
8
9
9
namespace Griddly . Mvc
@@ -19,6 +19,7 @@ public class DapperGriddlyResult<T> : GriddlyResult<T>
19
19
20
20
long ? _overallCount = null ;
21
21
bool _fixedSort ;
22
+ static readonly bool _hasOverallCount = typeof ( IHasOverallCount ) . IsAssignableFrom ( typeof ( T ) ) ;
22
23
23
24
public DapperGriddlyResult ( Func < IDbConnection > getConnection , string sql , object param , Func < IDbConnection , IDbTransaction , string , object , IEnumerable < T > > map = null , Action < IDbConnection , IDbTransaction , IList < T > > massage = null , bool fixedSort = false , Func < IDbTransaction > getTransaction = null )
24
25
: base ( null )
@@ -35,6 +36,46 @@ public DapperGriddlyResult(Func<IDbConnection> getConnection, string sql, object
35
36
_massage = massage ;
36
37
_fixedSort = fixedSort ;
37
38
_getTransaction = getTransaction ;
39
+
40
+ }
41
+
42
+ public override void PopulateSummaryValues ( GriddlySettings < T > settings )
43
+ {
44
+ List < GriddlyColumn > summaryColumns = settings . Columns . Where ( x => x . SummaryFunction != null ) . ToList ( ) ;
45
+
46
+ if ( summaryColumns . Any ( ) )
47
+ {
48
+ StringBuilder aggregateExpression = new StringBuilder ( ) ;
49
+
50
+ aggregateExpression . Append ( "SELECT " ) ;
51
+
52
+ for ( int i = 0 ; i < summaryColumns . Count ; i ++ )
53
+ {
54
+ if ( i > 0 )
55
+ aggregateExpression . Append ( ", " ) ;
56
+
57
+ GriddlyColumn col = summaryColumns [ i ] ;
58
+
59
+ aggregateExpression . AppendFormat ( "{0}({1}) AS _a{2}" , col . SummaryFunction , col . ExpressionString , i ) ;
60
+ }
61
+
62
+ string sql = string . Format ( "{0} FROM ({1}) [_proj]" , aggregateExpression . ToString ( ) , _sql ) ;
63
+
64
+ try
65
+ {
66
+ IDbConnection cn = _getConnection ( ) ;
67
+ IDbTransaction tx = _getTransaction != null ? _getTransaction ( ) : null ;
68
+
69
+ IDictionary < string , object > item = cn . Query ( sql , _param , tx ) . Single ( ) ;
70
+
71
+ for ( int i = 0 ; i < summaryColumns . Count ; i ++ )
72
+ summaryColumns [ i ] . SummaryValue = item [ "_a" + i ] ;
73
+ }
74
+ catch ( Exception ex )
75
+ {
76
+ throw new DapperGriddlyException ( "Error populating summary values." , sql , _param , ex ) ;
77
+ }
78
+ }
38
79
}
39
80
40
81
public override long GetCount ( )
@@ -62,7 +103,22 @@ public override long GetCount()
62
103
63
104
public override IList < T > GetPage ( int pageNumber , int pageSize , SortField [ ] sortFields )
64
105
{
65
- string sql = string . Format ( "{0} " + ( _fixedSort ? "" : "ORDER BY {1}" ) + " OFFSET {2} ROWS FETCH NEXT {3} ROWS ONLY" , _sql , BuildSortClause ( sortFields ) , pageNumber * pageSize , pageSize ) ;
106
+ string format ;
107
+
108
+ if ( ! _hasOverallCount || _sql . IndexOf ( "OverallCount" , StringComparison . InvariantCultureIgnoreCase ) != - 1 )
109
+ format = "{0} " + ( _fixedSort ? "" : "ORDER BY {1}" ) + " OFFSET {2} ROWS FETCH NEXT {3} ROWS ONLY" ;
110
+ else
111
+ // TODO: use dapper multimap Query<T, Dictionary<string, object>> to map all summary values in one go
112
+ format = @"
113
+ ;WITH _data AS (
114
+ {0}
115
+ ),
116
+ _count AS (
117
+ SELECT COUNT(0) AS OverallCount FROM _data
118
+ )
119
+ SELECT * FROM _data CROSS APPLY _count " + ( _fixedSort ? "" : "ORDER BY {1}" ) + " OFFSET {2} ROWS FETCH NEXT {3} ROWS ONLY" ;
120
+
121
+ string sql = string . Format ( format , _sql , BuildSortClause ( sortFields ) , pageNumber * pageSize , pageSize ) ;
66
122
67
123
return ExecuteQuery ( sql , _param ) ;
68
124
}
@@ -88,10 +144,14 @@ IList<T> ExecuteQuery(string sql, object param)
88
144
try
89
145
{
90
146
IEnumerable < T > result = _map ( _getConnection ( ) , _getTransaction != null ? _getTransaction ( ) : null , sql , param ) ;
91
- IHasOverallCount overallCount = result as IHasOverallCount ;
92
147
93
- if ( overallCount != null )
94
- _overallCount = overallCount . OverallCount ;
148
+ if ( _hasOverallCount )
149
+ {
150
+ IHasOverallCount overallCount = result as IHasOverallCount ;
151
+
152
+ if ( overallCount != null )
153
+ _overallCount = overallCount . OverallCount ;
154
+ }
95
155
96
156
IList < T > results = result . ToList ( ) ;
97
157
@@ -110,7 +170,7 @@ protected IEnumerable<T> DefaultMap(IDbConnection cn, IDbTransaction tx, string
110
170
{
111
171
IEnumerable < T > result = cn . Query < T > ( sql , param , tx ) ;
112
172
113
- if ( typeof ( IHasOverallCount ) . IsAssignableFrom ( typeof ( T ) ) )
173
+ if ( _hasOverallCount )
114
174
{
115
175
IHasOverallCount firstRow = result . FirstOrDefault ( ) as IHasOverallCount ;
116
176
ListPage < T > lp = new ListPage < T > ( ) ;
0 commit comments