Phiter
Phiter

Reputation: 14992

Linq query as extension method

I have a query that is used multiple times across the application, and I want to make a function to simplify it.

I have tried to make it a IQueryable, ICollection, nothing worked.

This is what I want to do, basically:

This is a query:

dias = db.T_AGENDA_AGENDAMENTOS
        .Where(r =>
                (
                    r.T_AGENDA_AGENDAMENTOS_CLIENTES_PARTICIPANTE.Count(
                            x => new[] { 1, 2, 5, 6, 7 }.Contains(x.T_AGENDA_AGENDAMENTOS_CLIENTES_PARTICIPANTE_STATUS.COD_PARTICIPANTE_STATUS) &&
                            x.T_CLIENTES.IND_ATIVO == "s" &&
                            x.IND_ATIVO == "s") < ((r.IND_AVULSO == "s") ? 1 : r.T_AGENDA_AGENDAMENTOS_FIXOS.NUM_MAXIMO_PARTICIPANTES)
                )
            )
    .Select(z => EntityFunctions.TruncateTime(z.DAT_INICIO))
    .Distinct().ToList();

This part inside r.T_AGENDA_AGENDAMENTOS_CLIENTES_PARTICIPANTE.Count( is the one used multiple times:

x => new[] { 1, 2, 5, 6, 7 }.Contains(x.T_AGENDA_AGENDAMENTOS_CLIENTES_PARTICIPANTE_STATUS.COD_PARTICIPANTE_STATUS) &&
x.T_CLIENTES.IND_ATIVO == "s" &&
x.IND_ATIVO == "s"

I wanted to turn this into a function or something, just so I don't need to copy-paste this all the time.

This is what I have tried, with no success:

public static ICollection<T_AGENDA_AGENDAMENTOS_CLIENTES_PARTICIPANTE> Ativos(this ICollection<T_AGENDA_AGENDAMENTOS_CLIENTES_PARTICIPANTE> source, int codAgendamento)
    {
            return source               
            .Where(x => !(new[] { 3, 4, 9 }
                    .Contains(x.T_AGENDA_AGENDAMENTOS_CLIENTES_PARTICIPANTE_STATUS.COD_PARTICIPANTE_STATUS)) &&
                    x.T_CLIENTES.IND_ATIVO == "s" &&
                    x.IND_ATIVO == "s" &&
                    x.COD_AGENDAMENTO == codAgendamento)
            .ToList();
    }

Then using the function like this:

dias = db.T_AGENDA_AGENDAMENTOS
        .Where(r =>
                (
                    r.T_AGENDA_AGENDAMENTOS_CLIENTES_PARTICIPANTE.Ativos(r.COD_AGENDAMENTO).Count() < ((r.IND_AVULSO == "s") ? 1 : r.T_AGENDA_AGENDAMENTOS_FIXOS.NUM_MAXIMO_PARTICIPANTES)
                )
        )
        .Select(z => EntityFunctions.TruncateTime(z.DAT_INICIO))
        .Distinct().ToList();

This is the error I'm getting:

Error CS1061 'ICollection' does not contain a definition for 'Ativos' and no extension method 'Ativos' accepting a first argument of type 'ICollection' could be found (are you missing a using directive or an assembly reference?)

What can be done?

Upvotes: 0

Views: 78

Answers (1)

AxelWass
AxelWass

Reputation: 1341

You could store your lambda expression in a variable or property:

Expression<Func<T_AGENDA_AGENDAMENTOS_CLIENTES_PARTICIPANTE, bool>> exp = x => new[] { 1, 2, 5, 6, 7 }.Contains(x.T_AGENDA_AGENDAMENTOS_CLIENTES_PARTICIPANTE_STATUS.COD_PARTICIPANTE_STATUS) &&
x.T_CLIENTES.IND_ATIVO == "s" &&
x.IND_ATIVO == "s"

and then use it in any expersion:

dias = db.T_AGENDA_AGENDAMENTOS
        .Where(
            r.T_AGENDA_AGENDAMENTOS_CLIENTES_PARTICIPANTE.Count(exp) < ((r.IND_AVULSO == "s") ? 1 : r.T_AGENDA_AGENDAMENTOS_FIXOS.NUM_MAXIMO_PARTICIPANTES)
        )
        .Select(z => EntityFunctions.TruncateTime(z.DAT_INICIO))
        .Distinct().ToList();

Is this what you need? This way you can reuse your lambda expression. You could store it in a static read only property.

If you need some parameters you could use a method instead:

Expression<Func<T_AGENDA_AGENDAMENTOS_CLIENTES_PARTICIPANTE, bool>> exp(int[] group){
    return  x => group.Contains(x.T_AGENDA_AGENDAMENTOS_CLIENTES_PARTICIPANTE_STATUS.COD_PARTICIPANTE_STATUS) &&
     x.T_CLIENTES.IND_ATIVO == "s" &&
     x.IND_ATIVO == "s"
}

Hope it helps!

Upvotes: 1

Related Questions