Skip to content

Instantly share code, notes, and snippets.

@NDiiong
Created June 10, 2021 11:22
Show Gist options
  • Save NDiiong/463842e58a002187a988e2141de5601a to your computer and use it in GitHub Desktop.
Save NDiiong/463842e58a002187a988e2141de5601a to your computer and use it in GitHub Desktop.
Specification
public class BaseSpecification<T> : ISpecification<T>
{
public BaseSpecification()
{
}
public BaseSpecification(Expression<Func<T, bool>> criteria)
{
Criteria = criteria;
}
public Expression<Func<T, bool>> Criteria { get; }
public List<Expression<Func<T, object>>> Includes { get; } = new List<Expression<Func<T, object>>>();
public Expression<Func<T, object>> OrderBy {get; private set;}
public Expression<Func<T, object>> OrderByDesc {get; private set;}
public int Take {get; private set;}
public int Skip {get; private set;}
public bool IsPagingEnabled{get; private set;}
protected void AddInclude(Expression<Func<T, object>> includeExpression)
{
Includes.Add(includeExpression);
}
protected void AddOrderBy(Expression<Func<T, object>> orderByExpression)
{
OrderBy = orderByExpression;
}
protected void AddOrderByDesc(Expression<Func<T, object>> orderByDescExpression)
{
OrderByDesc = orderByDescExpression;
}
protected void ApplyPaging(int skip, int take)
{
Skip = skip;
Take = take;
IsPagingEnabled = true;
}
}
public interface ISpecification<T>
{
Expression<Func<T, bool>> Criteria { get; }
List<Expression<Func<T, object>>> Includes { get; }
Expression<Func<T, object>> OrderBy { get; }
Expression<Func<T, object>> OrderByDesc { get; }
int Take {get;}
int Skip {get;}
bool IsPagingEnabled {get;}
}
public class SpecificationEvaluator<TEntity> where TEntity : BaseEntity
{
public static IQueryable<TEntity> GetQuery(IQueryable<TEntity> inputQuery, ISpecification<TEntity> spec)
{
var query = inputQuery;
if (spec.Criteria != null)
{
query = query.Where(spec.Criteria);
}
if (spec.OrderBy != null)
{
query = query.OrderBy(spec.OrderBy);
}
if (spec.OrderByDesc != null)
{
query = query.OrderByDescending(spec.OrderByDesc);
}
if (spec.IsPagingEnabled)
{
query = query.Skip(spec.Skip).Take(spec.Take);
}
query = spec.Includes.Aggregate(query, (current, include) => current.Include(include));
return query;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment