internal static async Task <ICollection <TModel> > GetAsync <TModel, TData>(this IStore store, IMapper mapper,
                                                                                    Expression <Func <TModel, bool> > filter = null,
                                                                                    Expression <Func <IQueryable <TModel>, IQueryable <TModel> > > queryFunc = null,
                                                                                    SelectExpandDefinition selectExpandDefinition = null)
            where TModel : BaseModel
            where TData : BaseData
        {
            return(mapper.ProjectTo
                   (
                       await store.GetQueryableAsync
                       (
                           Getfilter(),
                           GetQueryFunc()
                       ),
                       null,
                       GetIncludes()
                   )
                   .UpdateQueryable(selectExpandDefinition.GetExpansions(typeof(TModel)), mapper)
                   .ToList());

            Expression <Func <TModel, object> >[] GetIncludes()
            => selectExpandDefinition?.GetExpansionSelectors <TModel>().ToArray() ?? new Expression <Func <TModel, object> >[]
            {
            };

            Func <IQueryable <TData>, IQueryable <TData> > GetQueryFunc()
            => mapper.MapExpression <Expression <Func <IQueryable <TData>, IQueryable <TData> > > >(queryFunc)?.Compile();

            Expression <Func <TData, bool> > Getfilter()
            => mapper.MapExpression <Expression <Func <TData, bool> > >(filter);
        }
        internal static async Task <TReturn> QueryAsync <TModel, TData, TModelReturn, TDataReturn, TReturn>(this IStore store, IMapper mapper,
                                                                                                            Expression <Func <IQueryable <TModel>, TModelReturn> > queryFunc = null,
                                                                                                            ICollection <Expression <Func <IQueryable <TModel>, IIncludableQueryable <TModel, object> > > > includeProperties = null,
                                                                                                            SelectExpandDefinition selectExpandDefinition = null)
            where TModel : BaseModel
            where TData : BaseData
        {
            //Map the expressions
            Expression <Func <IQueryable <TData>, TDataReturn> > mappedQueryFunc = mapper.MapExpression <Expression <Func <IQueryable <TData>, TDataReturn> > >(queryFunc);
            ICollection <Expression <Func <IQueryable <TData>, IIncludableQueryable <TData, object> > > > includes = mapper.MapIncludesList <Expression <Func <IQueryable <TData>, IIncludableQueryable <TData, object> > > >(includeProperties);

            //Call the store
            TDataReturn result = await store.QueryAsync(mappedQueryFunc?.Compile(),
                                                        includes?.Select(i => i.Compile()).ToList());

            if (typeof(TReturn) == typeof(TDataReturn))
            {
                return((TReturn)(object)result);
            }

            if (typeof(TReturn).IsIQueryable() && typeof(TDataReturn).IsIQueryable())
            {
                return(GetProjection(typeof(TReturn).GetUnderlyingElementType()));
            }

            return(mapper.Map <TDataReturn, TReturn>(result));

            TReturn GetProjection(Type elementType)
            => (TReturn)mapper.ProjectTo
            (
                (IQueryable)result,
                elementType,
                selectExpandDefinition
            )
            .UpdateQueryable(elementType, selectExpandDefinition.GetExpansions(elementType), mapper);
        }