Doubt with Join between two classes

Asked

Viewed 167 times

1

I have the Classes:

    class Procedimento
    {
        public string CodProcedimento { get; set; }
        public string NomeProcedimento { get; set; }
        public string TpSexo { get; set; }
        public int IdadeMinima { get; set; }
        public int IdadeMaxima { get; set; }
        public string CodCbo { get; set; }
    }

    class RlProcedimentoRegistro
    {
        public string CodProcedimento { get; set; }
        public string Registro { get; set; }
    }

    class ProcedimentoCompleto
    {
        public string CodProcedimento { get; set; }
        public string NomeProcedimento { get; set; }
        public string TpSexo { get; set; }
        public int IdadeMinima { get; set; }
        public int IdadeMaxima { get; set; }
        public string CodCbo { get; set; }
        public string Registro { get; set; }
    }

I make a Join between the first two Classes to generate the third one (including the Record it property) and include it in a list:

listaProcedimentoCompleto = (from procedimento in listaProcedimento
                                 join rlProcedimento in listaRlProcedimentoCbo on procedimento.CodProcedimento equals rlProcedimento.CodProcedimento
                                 join rlProcedimentoRegistro in listaRlProcedimentoRegistro on procedimento.CodProcedimento equals rlProcedimentoRegistro.CodProcedimento
                                 where rlProcedimentoRegistro.Registro.Equals("01")
                                 orderby procedimento.NomeProcedimento
                                 select new ProcedimentoCompleto()
                                 {
                                     CodProcedimento = procedimento.CodProcedimento,
                                     IdadeMaxima = Convert.ToInt32(procedimento.IdadeMaxima / 12),
                                     IdadeMinima = Convert.ToInt32(procedimento.IdadeMinima / 12),
                                     NomeProcedimento = procedimento.NomeProcedimento,
                                     TpSexo = procedimento.TpSexo,
                                     CodCbo = rlProcedimento.CodCbo,
                                     Registro = rlProcedimentoRegistro.Registro
                                 }).ToList();

The idea is that: The Procedure Class has the codes of a table and the Procedural Class verifies if the record is 01, and creates the new Procedural Class.

Everything works fine so far. What I want is this:

The Procedural Classregistration DOES NOT CONTAIN all Codprocedures that exist in the Procedure Class, because there are procedures that do not have Registration, so there is no way to make the call.

As you can see in the code above, I can take all the Procedure that has the "01" Record (or other that I want), but I also want to take all that has Record "01" + those that does not contain any record, that is, those that do not exist in the table.

Let’s say I have the following

Procedimento.CodProcedimento = 1;
Procedimento.CodProcedimento = 2;
Procedimento.CodProcedimento = 3;
Procedimento.CodProcedimento = 4;

RlProcedimentoRegistro.CodProcedimento = 1, Registro = 01
RlProcedimentoRegistro.CodProcedimento = 3, Registro = 02
RlProcedimentoRegistro.CodProcedimento = 4, Registro = 01

I need to get back Procedures 1 and 4 (which has Record "01") + Procedure 2 (which is not listed in the table).

I tried to detail as much as possible, I hope you can understand well.

  • You just forgot to tell me what the type of each list is =D

  • The process is of the Procedure type. listaRlProcedimentRegister is of type Rlprocedural

  • And this listaRlProcedimentoCbo serves no purpose (in the context of the example)?

  • no. I didn’t realize she was there, but she filters the Procedure Class also by the Codcbo property. works normally too

1 answer

4


Missed using the DefaultIfEmpty in Join. This makes a left Join between the lists. See how your query

Obs.: I took some properties and that Join that was not part of the scope of the question because it was too confused, by the way, it is a tip, try to give some better names to your classes and also organize a little better your ideas in the code.

var lista = 

    (from procedimento in listaProcedimento

    join rlProcedimentoRegistro in listaRlProcedimentoRegistro 
        on procedimento.CodProcedimento equals rlProcedimentoRegistro.CodProcedimento
        into rlProcedimentoRegistro

    from procRegistro in rlProcedimentoRegistro.DefaultIfEmpty()

    where (procRegistro == null || procRegistro.Registro == "01")
    orderby procedimento.NomeProcedimento

    select new ProcedimentoCompleto
    {
        CodProcedimento = procedimento.CodProcedimento,
        TpSexo = procedimento.TpSexo,
        Registro = procRegistro?.Registro ?? "Nulo"
    }).ToList();

Here is a complete example, ready to run. You can see it running on . NET Fiddle

using static System.Console;
using System.Linq;

public class Program
{
    public static void Main()
    {
        var listaProcedimento = new [] 
        {
            new Procedimento { CodProcedimento = "Proc 01",},
            new Procedimento { CodProcedimento = "Proc 02" },
            new Procedimento { CodProcedimento = "Proc 03" },
            new Procedimento { CodProcedimento = "Proc 04" },
        };

        var listaRlProcedimentoRegistro = new [] 
        {
            new RlProcedimentoRegistro { CodProcedimento = "Proc 01", Registro = "01" },
            new RlProcedimentoRegistro { CodProcedimento = "Proc 02", Registro = "02" },
        };

        var lista = 

        (from procedimento in listaProcedimento

        join rlProcedimentoRegistro in listaRlProcedimentoRegistro 
            on procedimento.CodProcedimento equals rlProcedimentoRegistro.CodProcedimento
            into rlProcedimentoRegistro

        from procRegistro in rlProcedimentoRegistro.DefaultIfEmpty()

        where (procRegistro == null || procRegistro.Registro == "01")
        orderby procedimento.NomeProcedimento

        select new ProcedimentoCompleto
        {
            CodProcedimento = procedimento.CodProcedimento,
            TpSexo = procedimento.TpSexo,
            Registro = procRegistro?.Registro ?? "Nulo"
        }).ToList();

        foreach(var r in lista)
        {
            WriteLine($"{r.CodProcedimento} - {r.Registro}");
        }
    }
}

public class Procedimento
{
    public string CodProcedimento { get; set; }
    public string NomeProcedimento { get; set; }
    public string TpSexo { get; set; }
    public int IdadeMinima { get; set; }
    public int IdadeMaxima { get; set; }
    public string CodCbo { get; set; }
}

public class RlProcedimentoRegistro
{
    public string CodProcedimento { get; set; }
    public string Registro { get; set; }
}

public class ProcedimentoCompleto
{
    public string CodProcedimento { get; set; }
    public string NomeProcedimento { get; set; }
    public string TpSexo { get; set; }
    public int IdadeMinima { get; set; }
    public int IdadeMaxima { get; set; }
    public string CodCbo { get; set; }
    public string Registro { get; set; }
}
  • thanks, I will adapt here. which site you recommend me to study this type of query pro LINQ?

  • I don’t think I understand. You want a hint where to study this kind of thing?

  • That’s right, I want to study how to do my own thing. I can do using sql, but this way is a little different and I messed up a little bit to understand the logic

  • Bah, I don’t know how to help you with this. Maybe reading some more advanced material on Lilli is a good idea, but I don’t have anything to tell you.

  • blz, can you tell me what that line means: Registro = procRegistro?.Registro ?? "Nulo"

  • 1

    Can. procRegistro?.Registro tries to access the property Registro in procRegistro, however, if procRegistro for null the expression will not pop an error (which would be the default behavior without using the ?), instead the expression returns null. This operator is called null propagation operator. That part ?? "Nulo" means that if the return of the expression to the left is null, that is, if procRegistro or procRegistro.Registro for null the value of the expression will be the literal "Nulo".

  • 1

    You can read about the first operator on: What is the operator "."?. And about the second in What is the meaning of the operator "?"

Show 2 more comments

Browser other questions tagged

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