1: public static class Filtro
2: {
3: /// <summary>
4: /// Aplica uma lista de Filtros em uma entidade.
5: /// </summary>
6: /// <typeparam name="TEntidade">Instancia da entidade que será filtrada</typeparam>
7: /// <param name="entidadeOrigem">entidade que está sendo filtrada</param>
8: /// <param name="filtros">Lista de Filtros que deverão ser aplicadas</param>
9: /// <returns>Retorna um objeto com a lista das entidades filtradas</returns>
10: public static IQueryable<TEntidade> Filtrar<TEntidade>(this IQueryable<TEntidade> entidadeOrigem, List<FiltroEntidade> filtros) where TEntidade : class
11: {
12: //Pega apenas filtros que ainda não foram aplicados, em caso da lista de filtros ser reutilizada
13: List<FiltroEntidade> filtrosAplicar = filtros.Where(p => p.FiltroAplicado == false).ToList();
14:
15: foreach (FiltroEntidade item in filtrosAplicar)
16: {
17: entidadeOrigem = entidadeOrigem.Filtrar(item.NomePropriedade, item.tipoCompracao, item.ValorProcurar);
18: item.FiltroAplicado = true;
19: }
20:
21: return entidadeOrigem;
22:
23: }
24:
25:
26: /// <summary>
27: /// Aplica um unico Filtro
28: /// </summary>
29: /// <typeparam name="TEntidade">Instancia da Entidade</typeparam>
30: /// <param name="entidadeOrigem">objeto que será filtrada</param>
31: /// <param name="NomePropriedade">Nome da propriedade</param>
32: /// <param name="TipoComparacao">Tipo Comparação</param>
33: /// <param name="ValorProcurar">Valor que será filtrado filtrar</param>
34: /// <returns>Retorna um objeto com a lista das entidades filtradas</returns>
35: public static IQueryable<TEntidade> Filtrar<TEntidade>(this IQueryable<TEntidade> entidadeOrigem, string NomePropriedade, Minato.Entidades.FiltroEntidade.TipoComparacao TipoComparacao, string ValorProcurar)
36: where TEntidade : class
37: {
38:
39: Type type = typeof(TEntidade);
40: ConstantExpression procurarFiltro = Expression.Constant(ValorProcurar);
41: ParameterExpression parametro = Expression.Parameter(type, "p");
42: PropertyInfo propriedade = type.GetProperty(NomePropriedade);
43: Expression acesssoPropriedade = Expression.MakeMemberAccess(parametro, propriedade);
44:
45: Type tipo = Nullable.GetUnderlyingType(propriedade.PropertyType);
46:
47: if (tipo != null)
48: {
49: PropertyInfo valProp = typeof(Nullable<>).MakeGenericType(tipo).GetProperty("Value");
50: acesssoPropriedade = Expression.MakeMemberAccess(acesssoPropriedade, valProp);
51: }
52: else
53: {
54: tipo = acesssoPropriedade.Type;
55: }
56: if (tipo == typeof(Guid))
57: {
58: Guid guid = new Guid(ValorProcurar);
59: procurarFiltro = Expression.Constant(guid);
60: }
61: else
62: {
63: procurarFiltro = Expression.Constant(Convert.ChangeType(ValorProcurar, tipo));
64: }
65:
66:
67: MethodInfo startsWith = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) });
68: MethodInfo endsWith = typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) });
69: MethodInfo contains = typeof(string).GetMethod("Contains", new Type[] { typeof(string) });
70: Expression operacaoRealizar = null;
71: switch (TipoComparacao)
72: {
73: default:
74: case FiltroEntidade.TipoComparacao.Igual:
75: operacaoRealizar = Expression.Equal(acesssoPropriedade, procurarFiltro);
76: break;
77: case FiltroEntidade.TipoComparacao.Diferente:
78: operacaoRealizar = Expression.NotEqual(acesssoPropriedade, procurarFiltro);
79: break;
80:
81: case FiltroEntidade.TipoComparacao.Maior:
82: operacaoRealizar = Expression.GreaterThan(acesssoPropriedade, procurarFiltro);
83: break;
84: case FiltroEntidade.TipoComparacao.MaiorIgual:
85: operacaoRealizar = Expression.GreaterThanOrEqual(acesssoPropriedade, procurarFiltro);
86: break;
87:
88: case FiltroEntidade.TipoComparacao.Contem:
89: operacaoRealizar = Expression.Call(acesssoPropriedade, contains, procurarFiltro);
90: break;
91:
92: }
93: var ExpressaoWhere = Expression.Lambda(operacaoRealizar, parametro);
94: var ResultadoDaExpressao = Expression.Call(typeof(Queryable), "Where", new Type[] { entidadeOrigem.ElementType }, entidadeOrigem.Expression, ExpressaoWhere);
95:
96: return entidadeOrigem.Provider.CreateQuery<TEntidade>(ResultadoDaExpressao);
97: }
98: }