How to add include by expression in Repository Pattern C#

Asked

Viewed 464 times

0

I am creating a Repositorybase (Repository Pattern) with Entityframework Asp.Net Core, and in it I am creating a Where method, where I pass a Where expression of the entity. So far the method works perfectly, but in this same method I would like to pass an expression of includes to be added before SQL is performed.

Example:

public class RepositoryBase<TEntity> : IRepositoryBase<TEntity>
    where TEntity : EntityBase
{
    public RepositoryBase()
    {
        SetDbContext();
    }

    public void SetDbContext()
    {
        DbContext = new AberturaDeContasContextFactory().CreateDbContext();
    }

    public DbContext DbContext { get; set; }

    public string MessageError = "Erro ao {0}. Source: {1}, Exception: {2} ";

    public ICollection<TEntity> Where<TProperty>(Expression<Func<TEntity, bool>> where, params Expression<Func<TEntity, TProperty>>[] properties)
        where TProperty : EntityBase
    {
        try
        {
            var source = DbContext.Set<TEntity>().Where(where);

            if (!properties.IsObjectNull())
            {
                foreach (var prop in properties)
                {
                    source.Include(prop);
                }
            }
            return source.ToList();
        }
        catch (Exception ex)
        {
            throw new Exception(string.Format(MessageError, "Pesquisar todos com where", ex.Source, ex.Message));
        }
    }
}

When performing SQL, include is not working

public class HomeController : Controller
{
    public IActionResult Index()
    {
        Repository.Repositories.RepositoryBase<Cliente> repositorio = new Repository.Repositories.RepositoryBase<Cliente>();

        var a = repositorio.Where<Documento>(x => x.ClienteId == 1, doc => doc.Documento).ToList();

        return View();
    }
}

1 answer

1


I do it this way:

public virtual List<TEntity> SelectIncludes(Func<TEntity, bool> where, params Expression<Func<TEntity, object>>[] includes)
{
    IQueryable<TEntity> query = _context.Set<TEntity>();

    IEnumerable<TEntity> resultado = includes.Aggregate(query, (current, includeProperty) => current.Include(includeProperty));


    if (where != null)
        resultado = resultado.Where(where);

    return resultado.ToList();
}

To call him:

MinhaClasse minhaClasse = _meuRepositorio.SelectIncludes(p=> p.Id == 1, i=> i.ClasseRelacionadaUm, i=> i.ClasseRelacionadaDois).FirstOrDefault();

You may need to make some adjustments to how you are implementing Pattern.

  • Only one question @Barbetta, if I put the clause Where before the includes it does not work, really only works when it is put before the includes?

  • @Nicolabogar, yes, the includes must come first. Will Exception if you have any where access property of include, and if you don’t, you won’t joins

Browser other questions tagged

You are not signed in. Login or sign up in order to post.