LINQ for paging missing episodes

This commit is contained in:
Mark McDowall 2013-05-06 19:32:43 -07:00
commit d37c8c26c2
26 changed files with 318 additions and 57 deletions

View file

@ -72,6 +72,8 @@
<Compile Include="IDataMapper.cs" />
<Compile Include="LazyLoaded.cs" />
<Compile Include="Mapping\FluentMappings.cs" />
<Compile Include="QGen\SqliteRowCountQueryDecorator.cs" />
<Compile Include="QGen\SqlitePagingQueryDecorator.cs" />
<Compile Include="UnitOfWork.cs" />
<Compile Include="UnitOfWorkSharedContext.cs" />
<Compile Include="Mapping\ColumnMapBuilder.cs" />

View file

@ -241,7 +241,7 @@ namespace Marr.Data.QGen
string queryText = query.Generate();
_db.SqlMode = SqlModes.Text;
int count = (int)_db.ExecuteScalar(queryText);
int count = Convert.ToInt32(_db.ExecuteScalar(queryText));
_db.SqlMode = previousSqlMode;
return count;

View file

@ -56,6 +56,9 @@ namespace Marr.Data.QGen
case DB_SqlCeClient:
return new RowCountQueryDecorator(innerQuery);
case DB_SQLiteClient:
return new SqliteRowCountQueryDecorator(innerQuery);
default:
throw new NotImplementedException("Row count has not yet been implemented for this provider.");
}
@ -74,6 +77,9 @@ namespace Marr.Data.QGen
case DB_SqlCeClient:
return new PagingQueryDecorator(innerQuery, skip, take);
case DB_SQLiteClient:
return new SqlitePagingQueryDecorator(innerQuery, skip, take);
default:
throw new NotImplementedException("Paging has not yet been implemented for this provider.");
}

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
@ -77,13 +78,13 @@ namespace Marr.Data.QGen
internal SortBuilder<T> Order(Type declaringType, string propertyName)
{
_sortExpressions.Add(new SortColumn<T>(declaringType, propertyName, SortDirection.Asc));
_sortExpressions.Add(new SortColumn<T>(declaringType, propertyName, ListSortDirection.Ascending));
return this;
}
internal SortBuilder<T> OrderByDescending(Type declaringType, string propertyName)
{
_sortExpressions.Add(new SortColumn<T>(declaringType, propertyName, SortDirection.Desc));
_sortExpressions.Add(new SortColumn<T>(declaringType, propertyName, ListSortDirection.Descending));
return this;
}
@ -103,25 +104,37 @@ namespace Marr.Data.QGen
public virtual SortBuilder<T> OrderBy(Expression<Func<T, object>> sortExpression)
{
_sortExpressions.Add(new SortColumn<T>(sortExpression, SortDirection.Asc));
_sortExpressions.Add(new SortColumn<T>(sortExpression, ListSortDirection.Ascending));
return this;
}
public virtual SortBuilder<T> OrderBy(Expression<Func<T, object>> sortExpression, ListSortDirection sortDirection)
{
_sortExpressions.Add(new SortColumn<T>(sortExpression, sortDirection));
return this;
}
public virtual SortBuilder<T> OrderByDescending(Expression<Func<T, object>> sortExpression)
{
_sortExpressions.Add(new SortColumn<T>(sortExpression, SortDirection.Desc));
_sortExpressions.Add(new SortColumn<T>(sortExpression, ListSortDirection.Descending));
return this;
}
public virtual SortBuilder<T> ThenBy(Expression<Func<T, object>> sortExpression)
{
_sortExpressions.Add(new SortColumn<T>(sortExpression, SortDirection.Asc));
_sortExpressions.Add(new SortColumn<T>(sortExpression, ListSortDirection.Ascending));
return this;
}
public virtual SortBuilder<T> ThenBy(Expression<Func<T, object>> sortExpression, ListSortDirection sortDirection)
{
_sortExpressions.Add(new SortColumn<T>(sortExpression, sortDirection));
return this;
}
public virtual SortBuilder<T> ThenByDescending(Expression<Func<T, object>> sortExpression)
{
_sortExpressions.Add(new SortColumn<T>(sortExpression, SortDirection.Desc));
_sortExpressions.Add(new SortColumn<T>(sortExpression, ListSortDirection.Descending));
return this;
}
@ -198,7 +211,7 @@ namespace Marr.Data.QGen
string columnName = DataHelper.GetColumnName(sort.DeclaringType, sort.PropertyName, useAltName);
sb.Append(_dialect.CreateToken(string.Format("{0}.{1}", table.Alias, columnName)));
if (sort.Direction == SortDirection.Desc)
if (sort.Direction == ListSortDirection.Descending)
sb.Append(" DESC");
}

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
@ -9,7 +10,24 @@ namespace Marr.Data.QGen
{
public class SortColumn<T>
{
[Obsolete("Use ListSortDirection instead")]
public SortColumn(Expression<Func<T, object>> sortExpression, SortDirection direction)
{
MemberExpression me = GetMemberExpression(sortExpression.Body);
DeclaringType = me.Expression.Type;
PropertyName = me.Member.Name;
Direction = GetSortDirection(direction);
}
[Obsolete("Use ListSortDirection instead")]
public SortColumn(Type declaringType, string propertyName, SortDirection direction)
{
DeclaringType = declaringType;
PropertyName = propertyName;
Direction = GetSortDirection(direction);
}
public SortColumn(Expression<Func<T, object>> sortExpression, ListSortDirection direction)
{
MemberExpression me = GetMemberExpression(sortExpression.Body);
DeclaringType = me.Expression.Type;
@ -17,14 +35,14 @@ namespace Marr.Data.QGen
Direction = direction;
}
public SortColumn(Type declaringType, string propertyName, SortDirection direction)
public SortColumn(Type declaringType, string propertyName, ListSortDirection direction)
{
DeclaringType = declaringType;
PropertyName = propertyName;
Direction = direction;
}
public SortDirection Direction { get; private set; }
public ListSortDirection Direction { get; private set; }
public Type DeclaringType { get; private set; }
public string PropertyName { get; private set; }
@ -40,6 +58,13 @@ namespace Marr.Data.QGen
return me;
}
private ListSortDirection GetSortDirection(SortDirection direction)
{
if (direction == SortDirection.Desc) return ListSortDirection.Descending;
return ListSortDirection.Ascending;
}
}
public enum SortDirection

View file

@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Marr.Data.Mapping;
using Marr.Data.QGen.Dialects;
namespace Marr.Data.QGen
{
/// <summary>
/// Decorates the SelectQuery by wrapping it in a paging query.
/// </summary>
public class SqlitePagingQueryDecorator : IQuery
{
private SelectQuery _innerQuery;
private int _skip;
private int _take;
public SqlitePagingQueryDecorator(SelectQuery innerQuery, int skip, int take)
{
if (string.IsNullOrEmpty(innerQuery.OrderBy.ToString()))
{
throw new DataMappingException("A paged query must specify an order by clause.");
}
_innerQuery = innerQuery;
_skip = skip;
_take = take;
}
public string Generate()
{
StringBuilder sql = new StringBuilder();
_innerQuery.BuildSelectClause(sql);
_innerQuery.BuildFromClause(sql);
_innerQuery.BuildJoinClauses(sql);
_innerQuery.BuildWhereClause(sql);
_innerQuery.BuildOrderClause(sql);
sql.AppendLine(String.Format(" LIMIT {0},{1}", _skip, _take));
return sql.ToString();
}
public void BuildSelectClause(StringBuilder sql)
{
List<string> appended = new List<string>();
sql.Append("SELECT ");
int startIndex = sql.Length;
// COLUMNS
foreach (Table join in _innerQuery.Tables)
{
for (int i = 0; i < join.Columns.Count; i++)
{
var c = join.Columns[i];
if (sql.Length > startIndex && sql[sql.Length - 1] != ',')
sql.Append(",");
if (join is View)
{
string token = _innerQuery.Dialect.CreateToken(string.Concat(join.Alias, ".", _innerQuery.NameOrAltName(c.ColumnInfo)));
if (appended.Contains(token))
continue;
sql.Append(token);
appended.Add(token);
}
else
{
string token = string.Concat(join.Alias, ".", c.ColumnInfo.Name);
if (appended.Contains(token))
continue;
sql.Append(_innerQuery.Dialect.CreateToken(token));
if (_innerQuery.UseAltName && c.ColumnInfo.AltName != null && c.ColumnInfo.AltName != c.ColumnInfo.Name)
{
string altName = c.ColumnInfo.AltName;
sql.AppendFormat(" AS {0}", altName);
}
}
}
}
}
}
}

View file

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Marr.Data.QGen
{
public class SqliteRowCountQueryDecorator : IQuery
{
private SelectQuery _innerQuery;
public SqliteRowCountQueryDecorator(SelectQuery innerQuery)
{
_innerQuery = innerQuery;
}
public string Generate()
{
StringBuilder sql = new StringBuilder();
BuildSelectCountClause(sql);
_innerQuery.BuildFromClause(sql);
_innerQuery.BuildJoinClauses(sql);
_innerQuery.BuildWhereClause(sql);
return sql.ToString();
}
private void BuildSelectCountClause(StringBuilder sql)
{
sql.AppendLine("SELECT COUNT(*)");
}
}
}