Lambda, Where com subconsulta

Asked

Viewed 355 times

2

I need a consult like that on the lambda

    SELECT  ClienteId  --Aqui eu tenho varios campos do Cliente e estagioprocesso
    FROM    Cliente
    WHERE   ((SELECT  TOP (1) EP
                             FROM  estagioprocesso 
                             WHERE     (estagioprocesso.ClienteID = Cliente.ClienteId)
                             ORDER BY estagioprocesso.ID DESC)= 2)

That is, I check in the table Etapaprocess which is the last EP of this client (order by ID DESC) I take only 1 (top 1) and I check this EP if it is equal to the number I want return.

I want to bring all customer steps that the latest step has EP = id (2).

I tried to:

int id = 2;
var EP = db.EtapaProcess
       .Include(t => t.Cliente)
       .OrderByDescending(t => t.EP).Take(1).Where(x => x.EP == id)
       .ToList();

But it doesn’t work. Ex: There are 188 records that have already passed the EP=2, but that are with EP=2 only 5 records and with the above query returns me 0

  • It wouldn’t just be changing . Tolist(); to . Firstordefault();

  • I don’t think the query even processes, but returns 0, while the pattern I wanted would return 5 records. Looking at the query it generates by Diagnostic Tools is a complex query and there is nothing..

  • Are you sure you have x.EP == id? Try searching without include

  • actually x.EP ==id (in case id=2) has 188 records, but I want clients that the last Ep is ID=2 ai would only have 5..

  • Do so var EP = db.EtapaProcess.Take(1). Where(x => x.EP == id) . Tolist();

  • It’s almost... but I must get the last (1) customer id.. that is, I see there in the table I order by order autonumerable by desc return only 1 and then I check what is this EP if it is the 2 in case I recover the information... I will try to improve my doubt to be more clear.

  • 1

    All right, try posting what you want with PURE SQL

Show 3 more comments

2 answers

3

It is quite wrong your query. From what I understand of her, do the following:

var EP = db.EtapaProcess
   .Include(t => t.Cliente)
   .Where(x => x.EP == ep) // ep é uma variável que viria de algum lugar.
   .OrderByDescending(t => t.Id)
   .GroupBy(t => t.ClienteId);
  • You just changed the Order by right?

  • 1

    The order of extension methods affects the query generated as a whole.

  • It’s been so long since I used Linq I couldn’t remember... thank you, master

  • but that . Take(1) wouldn’t bring just one result? I want every customer where the last Andprocess is in the specified ID.

  • I updated the answer.

2


from what I understand, you want to bring all the customer steps that the latest step has the EP = id (2).

In this case, you will need to group by customer, to then make the comparison.

var epClientes = db.EtapaProcess
    .Include(etapa => etapa.Cliente)
    .GroupBy(etapa => etapa.ClienteID)
    .Where(grupo => grupo
        .OrderByDescending(etapa => etapa.ID)
        .Select(etapa => etapa.EP)
        .FirstOfDefault() == 2);

var EP = new List<EtapaProcess>();
foreach (var epCliente in epClientes)
{
    EP.AddRange(epCliente);
}

if you only want customers...

var clientes = db.EtapaProcess
    .Include(etapa => etapa.Cliente) // acredito que este include seja desnecessário.
    .GroupBy(etapa => etapa.Cliente)
    .Where(grupo => grupo
        .OrderByDescending(etapa => etapa.ID)
        .Select(etapa => etapa.EP)
        .FirstOfDefault() == 2)
    .Select(grupo => grupo.Key);

UPDATING

I believe you do not need to make a link to the customer table to get the expected result, you can use a query as below:

DECLARE @ep AS INT;
SET @ep = 2;

WITH CTE_Processos AS (
    SELECT 
        ROW_NUMBER() OVER (PARTITION BY ClienteID ORDER BY ID DESC) AS Ordem,
        ClienteID,
        EP
    FROM estagioprocesso
)

SELECT ClienteID FROM CTE_Processos WHERE Ordem = 1 AND EP = @ep;

In this case, do the following:

var clientes = db.EtapaProcess
    .GroupBy(etapa => etapa.ClienteID)
    .Where(grupo => grupo
        .OrderByDescending(etapa => etapa.ID)
        .Select(etapa => etapa.EP)
        .FirstOfDefault() == id)
    .Select(grupo => grupo.Key);
  • for or foreach ?

  • The method 'First' can only be used as a final query Operation. Consider using the method 'Firstordefault' in this instance Instead. this mistake appeared to me

  • sorry, really is the foreach, when error, replace the First for FirstOrDefault

  • now it has, but brought 11 results nothing to be.. but I think it’s right around, with groupby

  • @Dorathoto, I didn’t really understand what data you need, initially I thought I needed all the step history of customers who are in a certain step, then gave to understand that only customers would be enough.

  • It worked, in fact mine is like an Inner Join only brings the field where in both has resulted its as if it were a left Join brings the stages even if it does not have in the customer.. I just need to fix it and good...

  • 1

    @Dorathoto, take a look at the update of my answer, test both the query (sql), and the.

Show 2 more comments

Browser other questions tagged

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