Entity Framework relationship 1: N

2

Hello.

I have the following classes ...

Sales Class:

[Table("venda")]
public class Vendas
{        
    public Vendas()
    {
        ItensVendas= new List<ItensVendas>();

    }
    [Key]
    public int Id { get; set; }
    public string NOME_VENDA { get; set; }
    public DateTime? DATA { get; set; }
    public int ID_CLIENTE { get; set; }

    public virtual IEnumerable<ItensVendas> ItensVendas{ get; set; }

}

Class Items Sales:

[Table("ITENS_VENDA")]
public class ItensVendas
{
    [Key]
    public int Id { get; set; }
    public int ID_RPODUTO { get; set; }
    public int QTD { get; set; }
    public decimal VALOR { get; set; }

    [ForeignKey("venda")]
    public int VendaId { get; set; }

    public virtual Vendas venda { get; set; }

}

Controller:

     public class VendasController : ApiController
        {
            private Contexto ctx = new Contexto();

            [HttpGet]
            public  IEnumerable<Vendas> GetVendas()
            {



                using (Contexto vendaCtx = new Contexto()) {
                    return vendaCtx.Vendas.ToList();

              } 
            }
}

Context:

public class Contexto : DbContext
{
    public Contexto() : base("conn")
    { 
       this.Configuration.LazyLoadingEnabled = true;
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        base.OnModelCreating(modelBuilder);
    }

    public DbSet<Vendas> Vendas { get; set; }
    public DbSet<ItensVendas> ItensVendas { get; set; }
}

In the GetVends method of the controller, it returns a JSON containing the sales data, but the sales items come empty, as below.

[{"Id":1,"NOME_VENDA":"VENDA 1","DATA":"2017-11-15T20:08:52","ID_CLIENTE":1,"ITENSVENDAS":[]}]

I would like to bring the items of this sale too, how could I do that?

Thank you!

    
asked by anonymous 16.11.2017 / 00:18

3 answers

3

You can do as the example below using the "Include":

vendaCtx.Vendas 
  .Include(b => b.ItensVendas).ToList(); 
    
16.11.2017 / 00:29
3

You can use a sub select to include the sales items.

public  IEnumerable<Vendas> GetVendas()
{
    using (Contexto ctx = new Contexto()) 
    {
        return ctx.Vendas
        .Select(x => new Vendas
        {
            Id = x.Id,
            NOME_VENDA = x.NOME_VENDA,
            DATA = x.DATA,
            ID_CLIENTE = x.ID_CLIENTE,
            ItensVendas = ctx.ItensVendas.Where(i => i.VendaId == x.Id)
        })
        .ToList();

    } 
}
    
16.11.2017 / 16:13
2

Your configuration is probably LazyLoading = False; If you want to take a look at how it works, click here

In this regard, you have two options:

1- Deixa lazy loading = true

2- Give include in what you need to bring. Example:

using (Contexto vendaCtx = new Contexto()) 
{
   return vendaCtx.Vendas.Include(b => b.ItensVendas).ToList();
} 

In classes, your associations in the database must contain the virtual property and use ICollection instead of IEnumerable (lazyloading default). Therefore, you should change your sales class as follows:

[Table("venda")]
public class Vendas
{        
    public Vendas()
    {
        ItensVendas= new List<ItensVendas>();

    }
    [Key]
    public int Id { get; set; }
    public string NOME_VENDA { get; set; }
    public DateTime? DATA { get; set; }
    public int ID_CLIENTE { get; set; }

    public virtual ICollection<ItensVendas> ItensVendas{ get; set; }

}
    
16.11.2017 / 12:38