带分页的通用存储库

问题描述 投票:0回答:1

我很难让这种方法正常工作。我的目标是使用实体框架 (EF) 创建一个通用函数,该函数可以使用过滤器、包含和分页来搜索数据库。

我的困难在于过滤器。我想分析每种类型的变量;例如,仅在字符串不同于 null 或空时过滤字符串,在 guid 与 Guid.Empty 不同时过滤字符串,等等。

        public virtual async Task<PageFilter<TEntity>> GetWithFilterAndPagination(
            BaseRequestFilter pagination,
            List<Expression<Func<TEntity, object>>> includes,
            List<Expression<Func<TEntity, bool>>> filters)
        {
            try
            {
                using (var dbContext = IntegramillDbContextFactory.Create())
                {
                    var query = dbContext.Set<TEntity>().AsQueryable();

                    if (includes != null && includes.Any())
                    {
                        foreach (var include in includes)
                        {
                            query = query.Include(include);
                        }
                    }

                    if (filters != null && filters.Any())
                    {
                        foreach (var filter in filters)
                        {
                            query = query.Where(filter);
                        }
                    }

                    var totalCount = query.Count();
                    if (pagination.Offset != null)
                        query = query.Skip((int)pagination.Offset);

                    if (pagination.Take > 0)
                        query = query.Take(pagination.Take);

                    return new PageFilter<TEntity>(query.ToList(), totalCount);
                }
            }
            catch (Exception e)
            {
                Log.Error(e, "<{EventoId}> - Erro ao CONSULTAR " + typeof(TEntity).Name, "RepositoryError");
                throw e;
            }
        }

我已经尝试过这个但无法正常工作

                            var parameter = Expression.Parameter(typeof(TEntity), "x");
                            var expressaoBinaria = (BinaryExpression)filter.Body;
                            var propriedade = (MemberExpression)expressaoBinaria.Left;
                            var valor = expressaoBinaria.Right.ToObject();
                            var valor2 = expressaoBinaria.Right.ToString();
                            var valor3 = (MemberExpression)expressaoBinaria.Right;
                            var tipoDaPropriedade = propriedade.Type;

                            if (tipoDaPropriedade == typeof(string))
                            {
                                var teste2 = (string)valor2;
                                await Console.Out.WriteLineAsync("testeString");
                            }
                            if (tipoDaPropriedade == typeof(int))
                            {
                                var teste2 = int.Parse(valor2);
                                await Console.Out.WriteLineAsync("teste");
                            }
c# entity-framework lambda pagination
1个回答
0
投票

考虑到这些扩展方法:

public static class StringExt {
    public static bool IsNullOrEmpty(this string s) => String.IsNullOrEmpty(s);
}

public static class ExpressionExt {
    public static TResult Value<TResult>(this Expression e) => (TResult)((e is ConstantExpression c) ? c.Value : Expression.Lambda(e).Compile().DynamicInvoke());
}

您可以使用以下方法测试过滤器的 RHS:

var r = (filter.Body as BinaryExpression)?.Right;
var t = r?.Type;

if (t == typeof(string) && !r.Value<string>().IsNullOrEmpty())
    q = q.Where(filter);
else if (t == typeof(Guid) && r.Value<Guid>() != Guid.Empty)
    q = q.Where(filter);

请注意,如果过滤器不是预期的格式(例如,带有简单二进制表达式且 LHS 为参数的 lambda),那么它将被忽略。

也并不是说这不太可能很快,因为它使用

LambdaExpression.Compile()
来计算 RHS 的值。

© www.soinside.com 2019 - 2024. All rights reserved.