public IEnumerable <TDataModel> Search(IDataFilter <TDataModel> filter, IDataIncludes includes) { Checker.NotNullArgument(filter, nameof(filter)); return(QuerySearch(_query, filter, includes).ToList()); }
protected IQueryable <TDataModel> TryApplyIncludes( IQueryable <TDataModel> query, IDataIncludes includes) { return(includes != null ? includes.Includes.Aggregate(query, (q, i) => q.Include(i)) : query); }
protected IQueryable <TDataModel> QueryFind( IEntityType entityType, IQueryable <TDataModel> origin, object[] identifiers, IDataIncludes includes) { Checker.NotNullArgument(origin, nameof(origin)); Checker.NotNullArgument(entityType, nameof(entityType)); Checker.NotNullArgument(identifiers, nameof(identifiers)); var primaryKeys = entityType.FindPrimaryKey().Properties; if (identifiers.Length < 1) { // TODO: Implementar i18n/l10n throw new InvalidOperationException("At least one identifier must be informed."); } if (primaryKeys.Count() != identifiers.Count()) { // TODO: Implementar i18n/l10n throw new InvalidOperationException($"Number of primary keys configured in {typeof(TDataModel)} different than expected."); } var filter = new DataFilter <TDataModel>(); var param = Expression.Parameter(typeof(TDataModel), "e"); Expression <Func <TDataModel, bool> > filterExpression = null; foreach (var(pk, idx) in primaryKeys.Select((pk, idx) => (pk, idx))) { if (filterExpression != null) { filterExpression = Expression.Lambda <Func <TDataModel, bool> >( Expression.AndAlso( filterExpression.Body, Expression.Equal( Expression.PropertyOrField(param, pk.Name), Expression.Constant(identifiers[idx]) )), param ); } else { filterExpression = Expression.Lambda <Func <TDataModel, bool> >( Expression.Equal( Expression.PropertyOrField(param, pk.Name), Expression.Constant(identifiers[idx]) ), param ); } } filter.AddFilter(filterExpression); return(QuerySearch(origin, filter, includes)); }
public TDataModel Find(object[] identifiers, IDataIncludes includes = null) { Checker.NotNullArgument(identifiers, nameof(identifiers)); var entityType = _dbContext.Model.FindEntityType(typeof(TDataModel)); return(QueryFind(entityType, _query, identifiers, includes) .FirstOrDefault()); }
public PaginatedResult <TDataModel> LimitedGet(IDataLimiter <TDataModel> limiter, IDataIncludes includes) { Checker.NotNullArgument(limiter, nameof(limiter)); var(offset, limit, total, result) = QueryPreLimitResult(_query, limiter, includes); return(new PaginatedResult <TDataModel>( result.ToList(), offset, limit, total )); }
protected IQueryable <TDataModel> QuerySearch( IQueryable <TDataModel> origin, IDataFilter <TDataModel> filter, IDataIncludes includes) { Checker.NotNullArgument(origin, nameof(origin)); Checker.NotNullArgument(filter, nameof(filter)); var filterExpressions = filter.GetExpressions(); Checker.NotNullObject(filterExpressions, $"filter.{nameof(filter.GetExpressions)}()"); var query = filterExpressions.Aggregate(origin, (q, w) => q.Where(w)); return(TryApplyIncludes(query, includes)); }
public PaginatedResult <TDataModel> LimitedSearch(IDataFilter <TDataModel> filter, IDataLimiter <TDataModel> limiter, IDataIncludes includes) { Checker.NotNullArgument(filter, nameof(filter)); Checker.NotNullArgument(limiter, nameof(limiter)); var query = QuerySearch(_query, filter, includes); // A projeção já foi aplicada em QuerySearch(), // por isso não precisa ser repassada aqui var(offset, limit, total, result) = QueryPreLimitResult(query, limiter, null); return(new PaginatedResult <TDataModel>( result.ToList(), offset, limit, total )); }
public IEnumerable <TDataModel> GetAll(IDataIncludes includes) => TryApplyIncludes(_query, includes).ToList();
public TDataModel GetFirst(IDataFilter <TDataModel> filter, IDataIncludes includes = null) => QuerySearch(_query, filter, includes).FirstOrDefault();
/// <summary> /// Find an item stored by a data instance /// </summary> /// <param name="storage">Storage object</param> /// <param name="data">Data item</param> /// <param name="includes">Linked data to include</param> /// <returns>Instance of <see cref="TDataModel"/>, or null when not found</returns> public static TDataModel Find <TDataModel>(this IFindableStorage <TDataModel> storage, TDataModel data, IDataIncludes includes = null) where TDataModel : IIdentifiable { Checker.NotNullArgument(storage, nameof(storage)); Checker.NotNullArgument(data, nameof(data)); return(storage.Find(data.Identifiers, includes)); }
/// <summary> /// Find an item stored by identifier /// </summary> /// <param name="storage">Storage object</param> /// <param name="identifier">Item identifier</param> /// <param name="includes">Linked data to include</param> /// <returns>Instance of <see cref="TDataModel"/>, or null when not found</returns> public static TDataModel Find <TDataModel>(this IFindableStorage <TDataModel> storage, object identifier, IDataIncludes includes = null) where TDataModel : IIdentifiable { Checker.NotNullArgument(storage, nameof(storage)); Checker.NotNullArgument(identifier, nameof(identifier)); return(storage.Find(new object[] { identifier }, includes)); }
/// <summary> /// Query for operations that must return an <see cref="PaginatedResult{TDataModel}" /> /// </summary> /// <param name="limiter">Data limiter</param> /// <param name="origin">Original data query</param> /// <param name="includes">Data includes</param> /// <returns>Tuple of (offset, limit, total, result)</returns> protected (uint, uint, int, IQueryable <TDataModel>) QueryPreLimitResult( IQueryable <TDataModel> origin, IDataLimiter <TDataModel> limiter, IDataIncludes includes) { Checker.NotNullArgument(limiter, nameof(limiter)); Checker.NotNullArgument(origin, nameof(origin)); // Ensures offset range if (limiter.OffsetLimit.HasValue && (limiter.OffsetLimit.Value == 0 || limiter.OffsetLimit.Value > int.MaxValue)) { throw new ArgumentOutOfRangeException($"limiter.{limiter.OffsetLimit}"); } var result = TryApplyIncludes(origin, includes); IOrderedQueryable <TDataModel> orderBy = null; foreach (var sorter in limiter.GetSorters()) { if (orderBy == null) { orderBy = sorter.Descending ? result.OrderByDescending(sorter.Sorter) : result.OrderBy(sorter.Sorter); } else { orderBy = sorter.Descending ? orderBy.ThenByDescending(sorter.Sorter) : orderBy.ThenBy(sorter.Sorter); } } result = orderBy ?? result; uint offset; uint limit; var total = result.Count(); if (limiter.OffsetBegin.HasValue) { offset = limiter.OffsetBegin.Value; result = result.Skip(Convert.ToInt32(offset)); } else { offset = 0; } if (limiter.OffsetLimit.HasValue) { limit = limiter.OffsetLimit.Value; result = result.Take(Convert.ToInt32(limit)); } else { limit = Convert.ToUInt32(total); } return(offset, limit, total, result); }