Pass lambda statement by parameter - C# - Entity

Asked

Viewed 508 times

2

I have a method in which I need to pass only one select per parameter:

public List<TEntity> GetAll(Expression<Func<TEntity, TEntity>> Select)
{
    var query = Context.Set<TEntity>()
                .Where()
                .Select(Select).ToList();
    return query;
}

I need to pass a select that brings me the following fields: UsuarioId, Login, Senha, UsuarioTipoId e Descricao. It would be something more or less like following:

dgPesquisar.DataSource = UsuarioRepositorio.GetAll(u => new 
    { 
        x.UsuarioId, 
        x.Login, 
        x.Senha, 
        x.UsuarioTipoId, 
        x.Descricao
     });

It is necessary to do some Join in the tables?

Someone would know how to help me assemble the expression and how to pass it by parameter?

//Classes:
public class UsuarioTipoModel
{
    public int UsuarioTipoId { get; set; }
    public string Descricao { get; set; }

    public virtual ICollection<UsuarioModel> Usuario { get; set; }
}

public class UsuarioModel : PessoaModel
{
    public string Login { get; set; }
    public string Senha { get; set; }
    public int UsuarioTipoId { get; set; }

    public virtual UsuarioTipoModel UsuarioTipo { get; set; }

}

Repository

public abstract class BaseRepository<TEntity> : Interfaces.IRepository<TEntity> where TEntity : class
{
    private DbContext Context = null;
    protected DbSet<TEntity> Entity = null;

    public BaseRepository(DbContext Context)
    {
        this.Context = Context;
        this.Entity = Context.Set<TEntity>();
    }

    public void Add(TEntity Entity)
    {
        Context.Set<TEntity>().Add(Entity);
        Context.SaveChanges();
    }

    public void Delete(TEntity Entity)
    {
        Context.Set<TEntity>().Remove(Entity);
        Context.SaveChanges();
    }

    public TEntity Find(int Id)
    {
        var query = Context.Set<TEntity>().Find(Id);
        return query;
    }

    public List<TEntity> GetAll()
    {
        var query = Context.Set<TEntity>().ToList();
        return query;
    }

    public List<TEntity> GetAll(Expression<Func<TEntity, bool>> Predicate)
    {
        var query = Context.Set<TEntity>().Where(Predicate).ToList();
        return query;
    }

    public List<TEntity> GetAll(Expression<Func<TEntity, bool>> Predicate, Expression<Func<TEntity, TEntity>> Select)
    {
        var query = Context.Set<TEntity>()
            .Where(Predicate)
            .Select(Select).ToList();
        return query;
    }

    public void Update(TEntity Entity)
    {
        Context.Entry(Entity).State = EntityState.Modified;
        Context.SaveChanges();
    }
}
  • You can post your Repository class in full?

  • Blz.. I just updated.....

  • @Jalberromando, why didn’t you follow the method I gave you in the first question? http://answall.com/questions/163712/modifir-m%C3%A9todo-gen%C3%A9rico-para-unir-informa%C3%A7%C3%B5es-em-classes-c-windows-Forms , you are missing?

  • Opa.... I just couldn’t get the Tresult type right... Is it creating a new class with that name? Is it an Entity class? In my project it is underlined in red....

  • @Jalberromano Study Generics. A tip: forget the use of Repository with Entity Framework. You would never have gone through this problem if you didn’t use this Pattern "on top" of EF

  • TResult would be a datum created at runtime or could be a model created by a certain class, ie it is not required to create a class for this model, but, can be created. List<TResult> GetAll<TResult>(Expression<Func<TEntity, TResult>> select) if you have underlined in red you may need to indicate that Tresult is a class, if you are still having problems with that?

  • Hello Virgilio... I understand the idea... I’m returning a User model. So far so good. My User Model class inherits from Personal Model, and Personal Model Has a composition relationship with Personal Physicochemical and Personal Model.... The Getall method brings me everything straight, all the records. my question would be: How do I pass a Lambda statement oara the Getall bring me only a few fields from each table? ex: dgUsuario.Datasource = Usuariorepositorio.Getall("I DON’T KNOW HOW TO MAKE A SELECT LAMBDA HERE")....

Show 2 more comments

1 answer

1

In order to be able to say with more certainty what the code would look like in its context I will need the complete User repository class. But below is an idea of how the declaration of the method and its use can be made.

The method declaration would be as follows:

public List<TResult> GetAll<TResult>(Expression<Func<TEntity, TResult>> select)
{
    var query = Context.Set<TEntity>()
        .Include("UsuarioTipo")
        .Select(select)
        .ToList();
    return query;
}

The method call would be as follows:

UsuarioRetornoModel usuarioRetorno = UsuarioRepositorio.GetAll<UsuarioRetornoModel>(u => new UsuarioRetornoModel 
    { 
        UsuarioId = u.UsuarioId, 
        Login = u.Login, 
        Senha = u.Senha, 
        UsuarioTipoId = u.UsuarioTipo.UsuarioTipoId, 
        UsuarioTipoDescricao = u.UsuarioTipo.Descricao
     }
);

The class of return:

public class UsuarioRetornoModel
{
    public int UsuarioId { get; set; }
    public string Login { get; set; }
    public string Senha { get; set; }
    public int UsuarioTipoId { get; set; }
    public string UsuarioTipoDescricao { get; set; }
}

Updated

The properties UsuarioId, Login, Senha, UsuarioTipoId and UsuarioTipoDescricao were considered as properties of the class Usuarioretornomodel and the u within the lambda expression would be related to the user entity. To access properties of objects that come from a foreign key relation it is necessary to make use of include. The name of the property has been passed within include Include("UsuarioTipo").

Updated II

Make sure to implement the method in the interface.

public interface IRepository<TEntity>
{
    ...
    List<TResult> GetAll<TResult>(Expression<Func<TEntity, TResult>> select);
    ...
}
  • A question, where is DataSource?

  • I followed the code that was passed in the question to make the use example and considered the properties I believe have within this object.

  • I’m not criticizing, it’s an observation, the user is struggling, and it’s right there, include a classe DataSource (I would change the name already seen that in the net world this name can be confusing, because it exists in various contexts) for the user to understand where is each thing!

  • 1

    Beauty! Thank you for your feedback. I will edit the answer.

  • Just remembering your answer is correct, I had already done for him here, but, I don’t know why not to use: http://answall.com/questions/163712/modifir-m%C3%A9todo-gen%C3%A9rico-para-une-informa%C3%A7%C3%B5es-em-classes-c-windows-Forms

  • IRepository also warn that the method must be contained in the Interface, can be that too the confusion.

  • 1

    Maybe he’s still struggling with the return issue.

Show 2 more comments

Browser other questions tagged

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