Formatting with UNION and LINQ in C#

Asked

Viewed 192 times

2

I am using the following code to bring a list of companies with CNPJ formatted for Datagridview:

dgv.DataSource = db.pessoajuridica
                   .Select(d => new { d.idPessoa, d.nome, d.cnpj })
                   .AsEnumerable()
                   .Select(c => new { IdPessoa = c.idPessoa, Razão = c.nome, CNPJ = Convert.ToUInt64(c.cnpj).ToString(@"00\.000\.000\/0000\-00") })
                   .ToList();

And I’m using the following code to bring a list of individuals and legal entities to Datagridview:

dgv.DataSource = db.pessoajuridica
                   .Select(m => new { IdCliente = m.idPessoa, Nome = m.nome, Tipo = "Pessoa Jurídica", Documento = m.cnpj })
                   .Concat(db.pessoafisica
                   .Select(m => new { IdCliente = m.idPessoa, Nome = m.nome,  Tipo = "Pessoa Física", Documento = m.cpf }))
                   .ToList();

But I would like this second option to also come with formatting, one specific for CNPJ and another specific for CPF. But it’s not working...

The classes are defined below:

[Table("pessoa")]
public class pessoa
{
    [Key]
    public int idPessoa { get; set; }

    [Required]
    [StringLength(90)]
    public string nome { get; set; }
}


[Table("pessoafisica")]
public class pessoafisica : pessoa
{

    [StringLength(11)]
    public string cpf { get; set; }

    [StringLength(20)]
    public string rg { get; set; }

}


[Table("pessoajuridica")]
public class pessoajuridica : pessoa
{

    [StringLength(15)]
    public string cnpj { get; set; }

    [StringLength(255)]
    public string nomeFantasia { get; set; }

}

Does anyone know how I could do?

Thanks!!!

  • 1

    Why don’t you use the .ToString() as you did in the other query?

  • Because I can’t use . Tostring() inside the query... so I put . Asenumerable() and in the next select I used . Tostring()

3 answers

1

In this kind of case I believe that creating a specific type will solve, just do the desired formatting within the property set.

A very basic example of how to do this:

public class ResultadoPessoa
{
    private string _documento;

    public int IdCliente { get; set; }
    public string Nome { get; set; }
    public string Tipo { get; set; }

    public string Documento
    {
        get { return this._documento; }
        set
        {
            switch (this.Tipo)
            {
                case "Pessoa Jurídica":

                    this._documento = Convert.ToUInt64(value).ToString(@"00\.000\.000\/0000\-00");
                    break;

                case "Pessoa Física":

                    this._documento = Convert.ToUInt64(value).ToString(@"000\.000\.000\-00");
                    break;

                default:
                    this._documento = value;
                    break;
            }
        }
    }
}

That way, your consultation would be:

dgv.DataSource = db.PessoaJuridica.AsQueryable()
                                  .Select(m => new ResultadoPessoa { IdCliente = m.IdPessoa, Nome = m.Nome, Tipo = "Pessoa Jurídica", Documento = m.Cnpj })
                                  .Concat(db.PessoaFisica.AsQueryable()
                                  .Select(m => new ResultadoPessoa { IdCliente = m.IdPessoa, Nome = m.Nome, Tipo = "Pessoa Física", Documento = m.Cpf }))
                                  .ToList();
  • Hi Diego! Thanks for the suggestion, but in the suggested way I received the error "The specified type Member 'document' is not supported in LINQ to Entities. Only initializers, Entity Members, and Entity navigation properties are supported." I edited the question and placed the classes. Individual and Legal Person inherit the class person.

  • Felipe, I’m not sure what’s going on for you to be making this mistake. I created a project on github to illustrate how it works, it worked normally for me: https://github.com/jeronymo/SOpt_118995

1

I’d do it this way..

protected void Page_Load(object sender, EventArgs e)
{
    using (var Db = new WdbContext())
    {
        GridView1.DataSource =  Db.pessoa
            .Vw_PessoaTipos(Db)
            .ToList();

        GridView1.DataBind();
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WApp.Classes.Banco
{
    public class PessoaTipos
    {
        public rpessoa pessoa { get; set; }
        public rpessoafisica pessoafisica { get; set; }
        public rpessoajuridica pessoajuridica { get; set; }

        public String Documento
        {
            get { return pessoafisica.IdPessoaFisica > 0 ? pessoafisica.cpf : pessoajuridica.cnpj; }

        }

        public String Tipo
        {
            get { return pessoafisica.IdPessoaFisica > 0 ? "Pessoa Física" : "Pessoa Jurídica"; }
        }
    }

    public static class PessoaExt
    {
        public static IQueryable<PessoaTipos> Vw_PessoaTipos(
          this IQueryable<rpessoa> qrIn, WdbContext ctx)
        {
            return qrIn.
                Select(P => new PessoaTipos
                {
                    pessoa = P,
                    pessoafisica = ctx.pessoafisica.FirstOrDefault(PF => PF.IdPessoa == P.IdPessoa),
                    pessoajuridica = ctx.pessoajuridica.FirstOrDefault(PJ => PJ.IdPessoa == P.IdPessoa),
                });
        }
    }
}

0


Thank you all, but I found the solution.

In the parent class, I added a virtual attribute:

[Table("pessoa")]
public class pessoa
{
    [Key]
    public int idPessoa { get; set; }

    [Required]
    [StringLength(90)]
    public string nome { get; set; }

    [NotMapped]
    public virtual string documento { get; set; }
}

And I override this attribute in the child classes:

[Table("pessoafisica")]
public class pessoafisica : pessoa
{

    [StringLength(11)]
    public string cpf { get; set; }

    [StringLength(20)]
    public string rg { get; set; }

    [NotMapped]
    public override string documento
    {
        get
        {
            return Convert.ToUInt64(cpf).ToString(@"000\.000\.000\-00");
        }
    }
}

[Table("pessoajuridica")]
public class pessoajuridica : pessoa
{

    [StringLength(15)]
    public string cnpj { get; set; }

    [StringLength(255)]
    public string nomeFantasia { get; set; }

    [NotMapped]
    public override string documento
    {
        get
        {
            return Convert.ToUInt64(cnpj).ToString(@"00\.000\.000\/0000\-00");
        }
    }
}

Clean, simple and functional! Stay the solution for those who need it one day!

Browser other questions tagged

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