Where de query using multiple list properties

Asked

Viewed 102 times

0

I have the following scenario

public Teste[] GetTestes(List<TesteDTO> testeDTOs){
    IQueryble<Teste> query = GetAll<Teste>();
    //where ... 

}   


public class Teste()
{
    public int Prop1{ get; set;}
    public int Prop2 { get; set;}
    public int Prop3 { get; set;}

    //outras props
}

public class TesteDTO(){
    public int Prop1{ get; set;}
    public int Prop2 { get; set;}
    public int Prop3 { get; set;}
}

In the method GetTestes need to apply a Where to the query, using all the properties of TesteDTO. Virtually, ensure that the query will only return Testes "equal" to TestesDTO passed as parameter in the method.

  • Try and: query = query.Where(x => testeDTOs.Contains(x))

1 answer

1


You are falling into a matter of equality of different classes. To use a Contains or a ==, it is necessary that the two classes have some form of comparing.

To do this, create a method that returns bool given a specific comparison between class properties.

public class A 
{
    public int Prop1 { get; set; }
    public int Prop2 { get; set; }
    public int Prop3 { get; set; }  
    public bool Igual(B b)
    {
        return  Prop1 == b.Prop1 && Prop2 == b.Prop2 && Prop3 == b.Prop3; //Aplique sua lógica de comparação entre as duas classes aqui
    }
}
public class B
{
    public int Prop1 { get; set; }
    public int Prop2 { get; set; }
    public int Prop3 { get; set; }
}

Having this method, it is possible to implement item-to-item equality:

List<A> lista = new List<A>(); //Recebe a lista inicial
List<A> listaFinal = new List<A>(); //Filtra a lista com os parâmetros 
List<B> listaComparacao = new List<B>(); //Lista de filtro recebida por parâmetro
listaFinal = lista.Where(a=>listaComparacao.Any(b=>a.Igual(b))).ToList();

What the .Where last line makes:

1) a=> Receives in parameter with name a the instance of the class A that exists in the lista.

2) listaComparacao.Any(b=>a.Igual(b)) Scroll through the comparison list, checking which are "equal" to the items in the initial list, executing the method of equality between the two classes.

A point to note: The method Igual does not need to exist within the class A. Just be visible in the context of the method you will filter.

EDIT

If you do not have the initial list, it is possible to filter on top of the IQueriable:

IQueryble<A> query = GetAll<A>();
List<A> listaFinal = new List<A>(); //Recebe a lista filtrada
List<B> listaComparacao = new List<B>(); //Lista de filtro recebida por parâmetro
listaFinal = query.Where(a=>listaComparacao.Any(b=>a.Igual(b))).ToList();

EDIT (2)

If you want, you can make a direct comparison between objects of the two classes by the operator ==, making an Overload.

public class A 
{
    public int Prop1 { get; set; }
    public int Prop2 { get; set; }
    public int Prop3 { get; set; }  
    public bool Igual(B b)
    {
        return  Prop1 == b.Prop1 && Prop2 == b.Prop2 && Prop3 == b.Prop3; //Aplique sua lógica de comparação entre as duas classes aqui
    }
    public static bool operator ==(A a, B b)
    {
        return a.Igual(b);
    }

    public static bool operator !=(A a, B b)
    {
        return !a.Igual(b);
    }
}

Doing so, it is possible to use the query as follows:

IQueryble<A> query = GetAll<A>();
List<A> listaFinal = new List<A>(); //Recebe a lista filtrada
List<B> listaComparacao = new List<B>(); //Lista de filtro recebida por parâmetro
listaFinal = query.Where(a=>listaComparacao.Any(b=>a == b)).ToList();
  • The point is that I need to do this in a query, which will be executed in the database. I cannot bring all records from the first list to memory.

  • @Jonathanbarcela changed the answer.

Browser other questions tagged

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