Skip to content

Commit d67974c

Browse files
committed
Merge pull request #48 from programcsharp/result-types
More result types
2 parents 522b0e8 + 834c327 commit d67974c

8 files changed

+339
-217
lines changed

Griddly.Mvc/DapperGriddlyException.cs Griddly.Mvc/Exceptions/DapperGriddlyException.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
using System.Text;
55
using System.Threading.Tasks;
66

7-
namespace Griddly.Mvc
7+
namespace Griddly.Mvc.Exceptions
88
{
99
public class DapperGriddlyException : Exception
1010
{

Griddly.Mvc/Griddly.Mvc.csproj

+5-2
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,8 @@
8888
<Compile Include="..\Build\CommonAssemblyInfo.cs">
8989
<Link>Properties\CommonAssemblyInfo.cs</Link>
9090
</Compile>
91-
<Compile Include="DapperGriddlyException.cs" />
92-
<Compile Include="DapperGriddlyResult.cs" />
9391
<Compile Include="DynamicLinq.cs" />
92+
<Compile Include="Exceptions\DapperGriddlyException.cs" />
9493
<Compile Include="GriddlyFilterExtensions.cs" />
9594
<Compile Include="GriddlyHtmlFilter.cs" />
9695
<Compile Include="InternalExtensions.cs" />
@@ -109,6 +108,10 @@
109108
<Compile Include="IHasOverallCount.cs" />
110109
<Compile Include="ListPage.cs" />
111110
<Compile Include="Properties\AssemblyInfo.cs" />
111+
<Compile Include="Results\DapperResult.cs" />
112+
<Compile Include="Results\DapperSql2008Result.cs" />
113+
<Compile Include="Results\DapperSql2012Result.cs" />
114+
<Compile Include="Results\QueryableResult.cs" />
112115
<Compile Include="SelectListItemGroup.cs" />
113116
<Compile Include="SortField.cs" />
114117
</ItemGroup>

Griddly.Mvc/GriddlyResult.cs

+8-157
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,13 @@ public SortField[] GetSortFields(NameValueCollection items)
3939
}
4040
}
4141

42-
public class GriddlyResult<T> : GriddlyResult
42+
public abstract class GriddlyResult<T> : GriddlyResult
4343
{
44-
IQueryable<T> _result;
45-
Func<IQueryable<T>, IQueryable<T>> _massage = null;
46-
4744
public string ViewName { get; set; }
4845

49-
public GriddlyResult(IQueryable<T> result, string viewName = null, Func<IQueryable<T>, IQueryable<T>> massage = null)
46+
public GriddlyResult(string viewName = null)
5047
{
51-
_result = result;
5248
ViewName = viewName;
53-
_massage = massage;
5449
}
5550

5651
public override void ExecuteResult(ControllerContext context)
@@ -166,157 +161,13 @@ public override void ExecuteResult(ControllerContext context)
166161
}
167162
}
168163

169-
public virtual IEnumerable<T> GetAll(SortField[] sortFields)
170-
{
171-
IQueryable<T> sortedQuery = ApplySortFields(_result, sortFields);
172-
173-
if (_massage != null)
174-
sortedQuery = _massage(sortedQuery);
175-
176-
return sortedQuery;
177-
}
178-
179-
public virtual IList<T> GetPage(int pageNumber, int pageSize, SortField[] sortFields)
180-
{
181-
IQueryable<T> sortedQuery = ApplySortFields(_result, sortFields);
182-
183-
if (_massage != null)
184-
sortedQuery = _massage(sortedQuery);
185-
186-
return sortedQuery.Skip(pageNumber * pageSize).Take(pageSize).ToList();
187-
}
188-
189-
public virtual void PopulateSummaryValues(GriddlySettings<T> settings)
190-
{
191-
// Only works for linq to objects
192-
//List<GriddlyColumn> summaryColumns = settings.Columns.Where(x => x.SummaryFunction != null).ToList();
193-
194-
//if (summaryColumns.Any())
195-
//{
196-
// StringBuilder aggregateExpression = new StringBuilder();
197-
198-
// aggregateExpression.Append("new (");
199-
200-
// for (int i = 0; i < summaryColumns.Count; i++)
201-
// {
202-
// if (i > 0)
203-
// aggregateExpression.Append(", ");
164+
public abstract IEnumerable<T> GetAll(SortField[] sortFields);
165+
166+
public abstract IList<T> GetPage(int pageNumber, int pageSize, SortField[] sortFields);
167+
168+
public abstract void PopulateSummaryValues(GriddlySettings<T> settings);
204169

205-
// GriddlyColumn col = summaryColumns[i];
206-
207-
// aggregateExpression.AppendFormat("{0}({1}) AS _a{2}", col.SummaryFunction, col.ExpressionString, i);
208-
// }
209-
210-
// aggregateExpression.Append(")");
211-
212-
// var query = _result.GroupBy(x => 1).Select(aggregateExpression.ToString());
213-
// var item = query.Cast<object>().Single();
214-
// var type = item.GetType();
215-
216-
// for (int i = 0; i < summaryColumns.Count; i++)
217-
// summaryColumns[i].SummaryValue = type.GetProperty("_a" + i).GetValue(item);
218-
//}
219-
220-
// TODO: figure out how to get this in one query
221-
foreach (GriddlyColumn c in settings.Columns.Where(x => x.SummaryFunction != null))
222-
{
223-
switch (c.SummaryFunction.Value)
224-
{
225-
case SummaryAggregateFunction.Sum:
226-
case SummaryAggregateFunction.Average:
227-
case SummaryAggregateFunction.Min:
228-
case SummaryAggregateFunction.Max:
229-
c.SummaryValue = _result.Aggregate(c.SummaryFunction.Value.ToString(), c.ExpressionString);
230-
231-
break;
232-
233-
default:
234-
throw new InvalidOperationException(string.Format("Unknown summary function {0} for column {1}.", c.SummaryFunction, c.ExpressionString));
235-
}
236-
}
237-
}
238-
239-
public virtual long GetCount()
240-
{
241-
return _result.Count();
242-
}
243-
244-
protected static IQueryable<T> ApplySortFields(IQueryable<T> source, SortField[] sortFields)
245-
{
246-
IOrderedQueryable<T> sortedQuery = null;
247-
248-
if (sortFields != null)
249-
{
250-
for (int i = 0; i < sortFields.Length; i++)
251-
{
252-
SortField sortField = sortFields[i];
253-
254-
if (sortField.Direction == SortDirection.Ascending)
255-
{
256-
if (i == 0)
257-
sortedQuery = OrderBy(source, sortField.Field);
258-
else
259-
sortedQuery = ThenBy(sortedQuery, sortField.Field);
260-
}
261-
else
262-
{
263-
if (i == 0)
264-
sortedQuery = OrderByDescending(source, sortField.Field);
265-
else
266-
sortedQuery = ThenByDescending(sortedQuery, sortField.Field);
267-
}
268-
}
269-
}
270-
271-
return sortedQuery ?? source;
272-
}
273-
274-
// http://stackoverflow.com/a/233505/8037
275-
static IOrderedQueryable<T> OrderBy(IQueryable<T> source, string property)
276-
{
277-
return ApplyOrder(source, property, "OrderBy");
278-
}
279-
280-
static IOrderedQueryable<T> OrderByDescending(IQueryable<T> source, string property)
281-
{
282-
return ApplyOrder(source, property, "OrderByDescending");
283-
}
284-
285-
static IOrderedQueryable<T> ThenBy(IOrderedQueryable<T> source, string property)
286-
{
287-
return ApplyOrder(source, property, "ThenBy");
288-
}
289-
290-
static IOrderedQueryable<T> ThenByDescending(IOrderedQueryable<T> source, string property)
291-
{
292-
return ApplyOrder(source, property, "ThenByDescending");
293-
}
294-
295-
static IOrderedQueryable<T> ApplyOrder(IQueryable<T> source, string property, string methodName)
296-
{
297-
string[] props = property.Split('.');
298-
Type type = typeof(T);
299-
ParameterExpression arg = Expression.Parameter(type, "x");
300-
Expression expr = arg;
301-
foreach (string prop in props)
302-
{
303-
// use reflection (not ComponentModel) to mirror LINQ
304-
PropertyInfo pi = type.GetProperty(prop);
305-
expr = Expression.Property(expr, pi);
306-
type = pi.PropertyType;
307-
}
308-
Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);
309-
LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg);
310-
311-
object result = typeof(Queryable).GetMethods().Single(
312-
method => method.Name == methodName
313-
&& method.IsGenericMethodDefinition
314-
&& method.GetGenericArguments().Length == 2
315-
&& method.GetParameters().Length == 2)
316-
.MakeGenericMethod(typeof(T), type)
317-
.Invoke(null, new object[] { source, lambda });
318-
return (IOrderedQueryable<T>)result;
319-
}
170+
public abstract long GetCount();
320171
}
321172

322173
public enum GriddlyExportFormat

Griddly.Mvc/DapperGriddlyResult.cs Griddly.Mvc/Results/DapperResult.cs

+25-52
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,29 @@
11
using Dapper;
2+
using Griddly.Mvc.Exceptions;
23
using System;
34
using System.Collections.Generic;
45
using System.Data;
56
using System.Linq;
67
using System.Text;
78
using System.Web.Helpers;
89

9-
namespace Griddly.Mvc
10+
namespace Griddly.Mvc.Results
1011
{
11-
public class DapperGriddlyResult<T> : GriddlyResult<T>
12+
public abstract class DapperResult<T> : GriddlyResult<T>
1213
{
1314
Func<IDbConnection> _getConnection;
1415
Func<IDbTransaction> _getTransaction;
15-
string _sql;
16-
string _outerSqlTemplate;
1716
object _param;
1817
Func<IDbConnection, IDbTransaction, string, object, IEnumerable<T>> _map;
1918
Action<IDbConnection, IDbTransaction, IList<T>> _massage;
20-
2119
long? _overallCount = null;
22-
bool _fixedSort;
23-
static readonly bool _hasOverallCount = typeof(IHasOverallCount).IsAssignableFrom(typeof(T));
2420

25-
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, string outerSqlTemplate = "{0}")
21+
protected string _outerSqlTemplate;
22+
protected string _sql;
23+
protected bool _fixedSort;
24+
protected static readonly bool _hasOverallCount = typeof(IHasOverallCount).IsAssignableFrom(typeof(T));
25+
26+
public DapperResult(Func<IDbConnection> getConnection, string sql, object param, Func<IDbConnection, IDbTransaction, string, object, IEnumerable<T>> map, Action<IDbConnection, IDbTransaction, IList<T>> massage, bool fixedSort, Func<IDbTransaction> getTransaction, string outerSqlTemplate)
2627
: base(null)
2728
{
2829
_getConnection = getConnection;
@@ -66,10 +67,7 @@ public override void PopulateSummaryValues(GriddlySettings<T> settings)
6667

6768
try
6869
{
69-
IDbConnection cn = _getConnection();
70-
IDbTransaction tx = _getTransaction != null ? _getTransaction() : null;
71-
72-
IDictionary<string, object> item = cn.Query(sql, _param, tx).Single();
70+
IDictionary<string, object> item = ExecuteSingle<dynamic>(sql);
7371

7472
for (int i = 0; i < summaryColumns.Count; i++)
7573
summaryColumns[i].SummaryValue = item["_a" + i];
@@ -90,11 +88,7 @@ public override long GetCount()
9088

9189
try
9290
{
93-
IDbConnection cn = _getConnection();
94-
IDbTransaction tx = _getTransaction != null ? _getTransaction() : null;
95-
96-
_overallCount = cn.Query<long>(sql, _param, tx).Single();
97-
91+
_overallCount = ExecuteSingle<long>(sql);
9892
}
9993
catch (Exception ex)
10094
{
@@ -104,52 +98,31 @@ public override long GetCount()
10498

10599
return _overallCount.Value;
106100
}
107-
108-
public override IList<T> GetPage(int pageNumber, int pageSize, SortField[] sortFields)
101+
102+
protected string BuildSortClause(SortField[] sortFields)
109103
{
110-
string format;
111-
112-
if (!_hasOverallCount || _sql.IndexOf("OverallCount", StringComparison.InvariantCultureIgnoreCase) != -1)
113-
format = "{0} " + (_fixedSort ? "" : "ORDER BY {1}") + " OFFSET {2} ROWS FETCH NEXT {3} ROWS ONLY";
104+
if (sortFields != null && sortFields.Length > 0)
105+
return string.Join(",", sortFields.Select(x => x.Field + " " + (x.Direction == SortDirection.Ascending ? "ASC" : "DESC")));
114106
else
115-
// TODO: use dapper multimap Query<T, Dictionary<string, object>> to map all summary values in one go
116-
format = @"
117-
;WITH _data AS (
118-
{0}
119-
),
120-
_count AS (
121-
SELECT COUNT(0) AS OverallCount FROM _data
122-
)
123-
SELECT * FROM _data CROSS APPLY _count " + (_fixedSort ? "" : "ORDER BY {1}") + " OFFSET {2} ROWS FETCH NEXT {3} ROWS ONLY";
124-
125-
string sql = string.Format(_outerSqlTemplate,
126-
string.Format(format, _sql, BuildSortClause(sortFields), pageNumber * pageSize, pageSize));
127-
128-
return ExecuteQuery(sql, _param);
107+
return null;
129108
}
130109

131-
public override IEnumerable<T> GetAll(SortField[] sortFields)
110+
protected virtual X ExecuteSingle<X>(string sql)
132111
{
133-
string sql = string.Format(_outerSqlTemplate,
134-
_fixedSort ? _sql : string.Format("{0} ORDER BY {1}", _sql, BuildSortClause(sortFields)));
135-
136-
return ExecuteQuery(sql, _param);
137-
}
112+
113+
IDbConnection cn = _getConnection();
114+
IDbTransaction tx = _getTransaction != null ? _getTransaction() : null;
138115

139-
protected string BuildSortClause(SortField[] sortFields)
140-
{
141-
if (sortFields != null && sortFields.Length > 0)
142-
return string.Join(",", sortFields.Select(x => x.Field + " " + (x.Direction == SortDirection.Ascending ? "ASC" : "DESC")));
143-
else
144-
return "CURRENT_TIMESTAMP";
116+
return cn.Query<X>(sql, _param, tx).Single();
117+
145118
}
146119

147120
// TODO: return IEnumerable so we don't have to .ToList()
148-
IList<T> ExecuteQuery(string sql, object param)
121+
protected virtual IList<T> ExecuteQuery(string sql)
149122
{
150123
try
151124
{
152-
IEnumerable<T> result = _map(_getConnection(), _getTransaction != null ? _getTransaction() : null, sql, param);
125+
IEnumerable<T> result = _map(_getConnection(), _getTransaction != null ? _getTransaction() : null, sql, _param);
153126

154127
if (_hasOverallCount)
155128
{
@@ -168,7 +141,7 @@ IList<T> ExecuteQuery(string sql, object param)
168141
}
169142
catch (Exception ex)
170143
{
171-
throw new DapperGriddlyException("Error executing list query.", sql, param, ex);
144+
throw new DapperGriddlyException("Error executing list query.", sql, _param, ex);
172145
}
173146
}
174147

0 commit comments

Comments
 (0)