Help in riding a lambda from a foreach

Asked

Viewed 45 times

1

I have this foreach:

foreach (var row in responseObject)
{
    if (row.CDOrigem == request.CentroDeDistribuicaoId)
    {
        if (row.FaixasPreco == null || row.FaixasPreco.Count() == 0)
        {
            var uniqueItem = new ConsultarPrecoFaixaResponse();
            uniqueItem.PrecoBRL = row.ValorProduto;
            uniqueItem.PrecoUSD = row.ValorDolar;
            uniqueItem.CodigoMoeda = row.CodigoMoeda;
            faixaPrecoResponse.Add(uniqueItem);
        }
        else
        {
            foreach (var faixaPreco in row.FaixasPreco)
            {
                decimal cotacaoCalculada = 1;
                if (row.CodigoMoeda != CODIGO_MOEDA_REAL)
                    cotacaoCalculada = row.ValorProduto / row.ValorDolar;

                var faixaPrecoItem = new ConsultarPrecoFaixaResponse();
                if (row.CodigoMoeda != CODIGO_MOEDA_REAL)
                {
                    faixaPrecoItem.PrecoBRL = faixaPreco.Preco * cotacaoCalculada;
                    faixaPrecoItem.PrecoUSD = faixaPreco.Preco;
                }
                else
                {
                    faixaPrecoItem.PrecoBRL = faixaPreco.Preco;
                    faixaPrecoItem.PrecoUSD = 0;
                }

                faixaPrecoItem.CodigoMoeda = row.CodigoMoeda;
                faixaPrecoItem.QtdeMinimo = faixaPreco.Minimo;
                faixaPrecoItem.QtdeMaximo = faixaPreco.Maximo;
                faixaPrecoResponse.Add(faixaPrecoItem);
            }
        }
        break;
    }
}

From that, I started writing this lambda

var qry = responseObject.Where(obj => obj.CDOrigem == request.CentroDeDistribuicaoId)

Note that this Where has to do with the first if inside the foreach, but from there I started to get doubtful to follow. Don’t need code, just guidance on how to move forward, in relation to other if’s and etc..

EDIT1

That way is the right way?

var qry = responseObject
                .Where(obj => obj.CDOrigem == request.CentroDeDistribuicaoId)
                .Where(row => row.FaixasPreco == null || row.FaixasPreco.Count() == 0)
                .Select(sel => new ConsultarPrecoFaixaResponse
                {
                    PrecoBRL = sel.ValorProduto,
                    PrecoUSD = sel.ValorDolar,
                    CodigoMoeda = sel.CodigoMoeda,
                })

EDIT2

Based on the answer of João Martins, I did so and now comes the values of the products, but remains slow

var qry1 = from ro in responseObject
           .SelectMany(r => r.FaixasPreco, (ro, fp) => new { ro, fp })
                       select new ConsultarPrecoFaixaResponse()
                       {
                           PrecoBRL = (ro.ro.FaixasPreco == null || ro.ro.FaixasPreco.Count() == 0 ? ro.ro.ValorProduto : (ro.ro.CodigoMoeda == CODIGO_MOEDA_REAL ? ro.fp.Preco : (ro.fp.Preco * (ro.ro.ValorProduto / ro.ro.ValorDolar)))),
                           PrecoUSD = (ro.ro.FaixasPreco == null || ro.ro.FaixasPreco.Count() == 0 ? ro.ro.ValorDolar : (ro.ro.CodigoMoeda == CODIGO_MOEDA_REAL ? 0 : ro.fp.Preco)),
                           CodigoMoeda = ro.ro.CodigoMoeda,
                           QtdeMinimo = ro.fp.Minimo,
                           QtdeMaximo = ro.fp.Maximo
                       };

            faixaPrecoResponse.AddRange(qry1);
  • I made an issue, but that way it’s wrong. I need Join or things like that?

  • I took the Consult and made an anonymous select new and added another property like Faixaspreco, so I can follow with Where other than null and Count() higher than 0

  • This can depend a lot on the amount of information you have to return!

1 answer

1

I think you can do it this way:

var qry =  from ro in responseObject
           where ro.FaixasPreco == null || ro.FaixasPreco.Count() == 0
           select new ConsultarPrecoFaixaResponse()
           {
               PrecoBRL = ro.ValorProduto,
               PrecoUSD = ro.ValorDolar,
               CodigoMoeda = ro.CodigoMoeda
           };

var qry1 =  from ro in responseObject.Where(r => r.FaixasPreco != null && r.FaixasPreco.Count() > 0)
            .SelectMany(r => r.FaixasPreco, (ro, fp) => new { ro, fp })
            select new ConsultarPrecoFaixaResponse()
            {
                PrecoBRL = (ro.ro.CodigoMoeda == CODIGO_MOEDA_REAL ? fp.Preco : (fp.Preco * (ro.ValorProduto/ro.ValorDolar))),
                PrecoUSD = (ro.ro.CodigoMoeda == CODIGO_MOEDA_REAL ? 0 : fp.Preco),
                CodigoMoeda = ro.ro.CodigoMoeda,
                QtdeMinimo = fp.Minimo,
                QtdeMaximo = fp.Maximo
            };

If the result to be returned is a merge of the two results, we can put them together this way:

var qry2 = qry.Union(qry1);
  • A question: The whole method’s Return is this: return new ConsultarPrecoReader(faixaPrecoResponse); and how do I assign these two Linqs in the method’s Return, how do I do this? Should I do this: faixaPrecoResponse.AddRange(qry);
 faixaPrecoResponse.AddRange(qry1);

  • Edited response to include the return :)

  • The problem is that the values in the lambda are coming zeroed and if I return to the foreach, comes value and continues to delay, that I do not understand yet

  • But does it return the correct records? Only the values go wrong?

  • Maybe a left Join with the prices I can, I guess

  • If the class FaixasPreco has a connecting column with the responseObject yes, you can make JOIN!

Show 1 more comment

Browser other questions tagged

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