Automapper with Expression

Asked

Viewed 620 times

2

I am making a generic repository and came across the following situation.

In this call I can do the mapping and it works perfect.

    public IEnumerable<PaisViewModel> GetAll()
    {
        return Mapper.Map<IEnumerable<Pais>, IEnumerable<PaisViewModel>>(_paisService.GetAll());
    }

But in this case I’m having difficulties because it uses Express. Being that my entity is Parents and I use Viewmodelpais. How do I automapper with Expression?

    public IEnumerable<PaisViewModel> Find(Expression<Func<PaisViewModel, bool>> predicate)
    {
       return Mapper.Map<IEnumerable<Pais>, IEnumerable<PaisViewModel>>(_paisService.Find(predicate));
    }

This project follows this architecture

http://eduardopires.net.br/2014/10/tutorial-asp-net-mvc-5-ddd-ef-automapper-ioc-dicas-e-truques/

I am beginner in C# I came across this situation where I have to implement these generic CRUD.

Domain Layer

namespace Sistema.Domain.Entities
{
    public class Pais
    {
        public int PaisId { get; set; }
        public string Codigo { get; set; }
        public string Nome { get; set; }
    }
}

Service Layer

namespace Sistema.Domain.Interfaces.Services
{
    public interface IServiceBase<TEntity> where TEntity : class
    {
        IEnumerable<TEntity> GetAll();
        TEntity GetById(object id);
        IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);
        void Add(TEntity entity);
        void Update(TEntity entity);
        void Remove(TEntity entity);
    }
}

namespace Sistema.Domain.Services
{
    public class ServiceBase<TEntity> : IDisposable, IServiceBase<TEntity> where TEntity : class
    {

        private readonly IRepositoryBase<TEntity> _repository;

        public ServiceBase(IRepositoryBase<TEntity> repository)
        {
            _repository = repository;
        }

        public virtual IEnumerable<TEntity> GetAll()
        {
            return _repository.GetAll();
        }

        public TEntity GetById(object id)
        {
            return _repository.GetById(id);
        }

        public virtual IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
        {
            return _repository.Find(predicate);
        }

        public virtual void Add(TEntity entity)
        {
            _repository.Add(entity);
        }

        public virtual void Update(TEntity entity)
        {
            _repository.Update(entity);
        }

        public virtual void Remove(TEntity entity)
        {
            _repository.Remove(entity);
        }

        public virtual void Dispose()
        {
            _repository.Dispose();
        } 
    }
}

Application Layer

namespace Sistema.Application.ViewModels
{
    public class PaisViewModel
    {
        public int PaisId { get; set; }
        public string Codigo { get; set; }
        public string Nome { get; set; }
    }
}

namespace Sistema.Application.Interfaces
{
    public interface IPaisAppService : IDisposable
    {
        IEnumerable<PaisViewModel> GetAll();
        PaisViewModel GetById(object id);
        IEnumerable<PaisViewModel> Find(Expression<Func<PaisViewModel, bool>> predicate);
        void Add(PaisViewModel paisViewModel);
        void Update(PaisViewModel paisViewModel);
        void Remove(PaisViewModel paisViewModel);  
    }
}


namespace Sistema.Application
{
    public class PaisAppService : AppServiceBase<SistemaContext>, IPaisAppService
    {

        private readonly IPaisService _paisService;

        public PaisAppService(IPaisService cidadeService)
        {
            _paisService = cidadeService;
        }

        public IEnumerable<PaisViewModel> GetAll()
        {
            return Mapper.Map<IEnumerable<Pais>, IEnumerable<PaisViewModel>>(_paisService.GetAll());
        }

        public PaisViewModel GetById(object id)
        {
            return Mapper.Map<Pais, PaisViewModel>(_paisService.GetById(id));
        }

        public IEnumerable<PaisViewModel> Find(Expression<Func<PaisViewModel, bool>> predicate)
        {
            // Não estou conseguindo implementar
            throw new NotImplementedException();
        }

        public void Add(PaisViewModel paisViewModel)
        {
            throw new NotImplementedException();
        }

        public void Update(PaisViewModel paisViewModel)
        {
            throw new NotImplementedException();
        }

        public void Remove(PaisViewModel paisViewModel)
        {
            throw new NotImplementedException();
        }

        public void Dispose()
        {
            throw new NotImplementedException();
        }
    }
}



    public IEnumerable<PaisViewModel> Find(Expression<Func<PaisViewModel, bool>> predicate)
    {
        // Não estou conseguindo implementar
        throw new NotImplementedException();
    }
  • I moved your edit to your question, this is where the edit should be. I will analyze the code.

  • Look, in this tutorial project there is no Find. Did you implement it on the outside? Could you add the implementation of Find of the Repositorybase?

  • The people who passed me this project already passed this way, my function would just implement. I will analyze.

  • Shows how Find() in RepositoryBase that I help you.

  • public virtual Ienumerable<Tentity> Find(Expression<Func<Tentity, bool>> predicate) { Return Dbset.Where(predicate); }

  • See the edition of my reply, this was because you are using the Expression<Func<PaisViewModel,bool>> and the Find do PaisService is expecting a Expression<Func<Pais,bool>>

  • Thanks for the help that’s right. It worked

Show 2 more comments

2 answers

1

You can make the predicate mapper:

var newPredicate = Mapper.Map<Expression<Func<Class, bool>>>

Example:

public IEnumerable<PaisViewModel> Search(Expression<Func<PaisViewModel, bool>> predicate)
{
var newPredicate = Mapper.Map<Expression<Func<Pais, bool>>>(predicate);
return Mapper.Map<IEnumerable<PaisViewModel>>(_paisService.Search(newPredicate));
}

1


In case of making Automapper with Expression, you have to use the .Where() and not the .Find().

The .Find() returns a single element and you are trying to map to a Collection.

Would look like this:

public IEnumerable<PaisViewModel> Find(Expression<Func<PaisViewModel, bool>> predicate)
{
   return Mapper.Map<IEnumerable<Pais>, IEnumerable<PaisViewModel>>(_paisService.Where(predicate));
}

Or

public PaisViewModel Find(Expression<Func<PaisViewModel, bool>> predicate)
{
   return Mapper.Map<Pais, PaisViewModel>(_paisService.Find(predicate));
}

Edit

Apparently the reason for the error is that you are using:

Expression<Func<PaisViewModel,bool>>

When I should really use:

Expression<Func<Pais,bool>>
  • My method returns a Ienumerable in this case the following error happens. It would have to change my methods to return a Iqueryble?

  • Error 1 Instance argument: cannot Convert from 'Sistema.domain.Interfaces.Services.Ipaisservice' to 'System.Linq.Iqueryable<Sistema.Application.Viewmodels.Paisviewmodel>' C:.. System src System.Application Paisappservice.Cs 58 78 System.Application

  • Error 2 'Sistema.Domain.Interfaces.Services.IPaisService' does not contain a definition for 'Where' and the best extension method overload 'System.Linq.Queryable.Where<TSource>(System.Linq.IQueryable<TSource>, System.Linq.Expressions.Expression<System.Func<TSource,bool>>)' has some invalid Arguments C:.. System src System.Application Paisappservice.Cs 58 78 System.Application

  • These are my interfaces

  • IEnumerable<TEntity> GetAll();&#xA; TEntity GetById(object id);&#xA; IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);&#xA; void Add(TEntity entity);&#xA; void Update(TEntity entity);&#xA; void Remove(TEntity entity);

  • @Gilmar, are these interfaces from your service? Could you show how Find(Expression<Func<Tentity, bool>>)?

Show 1 more comment

Browser other questions tagged

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