.Orderby dynamically in Lambda

Asked

Viewed 158 times

1

I have a field int called OrdemDosProdutosDestaque where I store products order preference (My customer choosing and storing in the database).

ex:

1=Aleatório
2=Preço
3=Referência
4=Categoria
etc..

Model Configcliente

[Column("int_SORT")]
    public int OrdemDosProdutosDestaque { get; set; }

    public string OrdemDestaque() {
//tentativa de transformar int em algo utilizavel
        var retorno = "";
        if (OrdemDosProdutosDestaque == 1)
        {
            retorno = "Aleatório";
        }
        else if (OrdemDosProdutosDestaque == 2)
        {
            retorno = "Valor";
        }
        //etc

        return retorno;
    }

Then there in my controller i want to order the products according to customer’s option.

Something like:

IQueryable<produto> produtos = db.produtos
                        .Include(i => i.Cidade)
                        .Where(w => w.ClienteId == IDC && w.EstaAutorizado);

            if (ImovelEmDestaque)
            {
               produtos = produtos.OrderBy(o => o.cliente.ConfigCliente.OrdemDosProdutosDestaque);
            };

Of course in that case I’m still sending to the field int, but how to send properties as value, category, there model Product, or random, or otherwise model like photos?

OBS: In the Model Produto created a field bool TemFotos(), so I can easily know if you have photos or not.

1 answer

2


That one Include should therefore be in line with the principle of early loading:

IQueryable<produto> produtos = db.produtos
                                 .Include(i => i.Cidade)
                                 .Include(i => i.Cliente.ConfigCliente)
                                 .Where(w => w.ClienteId == IDC && w.EstaAutorizado);

Only you want a special operation of ORDER BY on top of information you still don’t have. Better select the customer before:

var cliente = db.Clientes
                .Include(c => c.ConfigCliente)
                .FirstOrDefault(c => c.ClienteId == IDC);

And then use the OrdemDosProdutosDestaque with a switch:

switch (cliente.ConfigCliente.OrdemDosProdutosDestaque)
{
    case 2:
        produtos = produtos.OrderBy(p => p.Valor);
        break;
    ...
}

Already the random in Linq to Entities needs the list already materialized (ie, after to ToList(). You can do it two ways:

1. .Shuffle()

if (cliente.ConfigCliente.OrdemDosProdutosDestaque == 1) {
    var lista = produtos.ToList().Shuffle();
}

2. Guids

if (cliente.ConfigCliente.OrdemDosProdutosDestaque == 1) {
    var lista = produtos.ToList().OrderBy(p => Guid.NewGuid());
}

EDIT

The @Tobymosque gave the great suggestion to try to order by Guid before materializing the list, and it works:

if (cliente.ConfigCliente.OrdemDosProdutosDestaque == 1) {
    var lista = produtos.OrderBy(p => Guid.NewGuid()).ToList();
}

The command can therefore be used in the switch.

  • 2

    Gypsy, I believe the Guid.NewGuid() is translated to NEWID(), then the .OrderBy(p => Guid.NewGuid()) will transform into ORDER BY NEWID(), then it should be possible to query "Random" without the ToList().

  • You’re right. In SQL it worked.

Browser other questions tagged

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