Implementando vários ‘Includes’ em repositório genérico

Olá pessoal,

Para quem conhece o Repositório Genérico que colocamos no CodePlex (http://dataplataform.codeplex.com) podem perceber que no caso de você desejar incluir em alguma consulta Linq uma propriedade relacionada ao objeto que estiver consultando deveria colocar isso em uma string.

No entanto sabemos que isso não é muito bom, pois caso seja feita alguma mudança no nome de uma propriedade ficará ruim manter isso, inclusive também se escrever errado o nome da proprieade ocorrerá erro somente em tempo de execução.

O código que temos hoje no repositório fornece um método abaixo para o EF 4.1, com isso vamos entender melhor o que estou falando.

[csharp]
public IList<TSource> GetAll(string include)
{
try
{
IList<TSource> result = Context.Set<TSource>()
.Include(include).ToList();
return result;
}
catch (Exception ex)
{
if (ex.InnerException != null)
throw new Exception(ex.InnerException.Message, ex);
throw new Exception(ex.Message, ex);
}
}
[/csharp]

Neste caso vamos utilizar o método chamando assim:

[csharp]
var listaCategorias = repCategory.GetAll("Products");
[/csharp]

No entando ficaria ainda mais complicado que quiser indicar mais de uma propriedade, para o caso do EF teríamos de separar com “,” (vírgula), e se for WCF Data Services seria com “/”. Então não ficaria muito legal cuidar disto.

Mas como diríamos “seus problemas acabaram” :)

Podemos resolver isso usando o próprio ‘Linq’ e nossa amiga ‘Lambda’, então nosso método GetAll do repositório genérico ficaria assim:

[csharp]
public virtual IList<TSource> GetAll(params Expression<Func<TSource, object>>[] include)
{
try
{
if (include.Length == 0)
throw new Exception("Número de parametros inválido.");

var query = Context.Set<TSource>().AsQueryable();

query = include.Aggregate(query, (current, exp) => current.Include(exp));

IList<TSource> result = query.ToList();
return result;
}
catch (Exception ex)
{
if (ex.InnerException != null)
throw new Exception(ex.InnerException.Message, ex);
throw new Exception(ex.Message, ex);
}
}
[/csharp]

Com isso para utilizar o método agora podemos passar como parâmetro uma lista de expressões e em nosso exemplo usado fica assim:

[csharp]
var listaCategorias = repCategory.GetAll(c => c.Products);
[/csharp]

O repositório foi atualizado no CodePlex e você poderá baixá-lo.

Esta melhoria foi muito útil em um projeto que estamos utilizando na empresa e espero também que tenham benefícios com ela.

Até mais!

Deixe um comentário