How to do a complex query in SQL in .NET MVC

3

I would like to know how to make a query, using multiple fields, multiple tables with inner joins in ASP.NET MVC without having to put the SQL string in the code, using the Entity Framework.

Currently, without using the string in the code, I only know how to do basic queries at the base.

    
asked by anonymous 19.06.2014 / 19:47

1 answer

6

Suppose Model of Product :

public class Produto 
{ 
    [Key]
    public Guid ProdutoId { get; set; }
    public Guid CategoriaId { get; set; }
    public Guid FabricanteId { get; set; }

    [Required]
    public String Descricao { get; set; } 
    [Required]
    public Decimal Preco { get; set; }

    public virtual Categoria Categoria { get; set; }
    public virtual Fabricante Fabricante { get; set; }
}

Notice that Produto has two relationships: Categoria and Fabricante . Usually the Entity Framework is already configured to bring in all the data alone when requested by the code. This is an implementation that uses lazy load . In this implementation, selecting Produto , Categoria and Fabricante receive temporary objects (Dynamic Proxies). These objects, when asked to provide the value of some property (for example, the name of a Categoria ), are replaced by the objects of the Model itself. In this process, selections or local cache searches occur, depending on the situation.

Basic Selections

The sentence below:

var produtos = context.Produtos.ToList();

is the equivalent of doing:

select * from Produtos

context is a variable that represents the context of your application, this class object derived from DbContext .

Selecting Dependent Entities

To bring in the manufacturers and categories of each product, the idea is to use the following command:

var produtos = context.Produtos
               .Include(p => p.Fabricante)
               .Include(p => p.Categoria)
               .ToList();

Which is equivalent to:

select * from Produtos
inner join Fabricantes on Fabricantes.FabricanteId = Produtos.FabricanteId
inner join Categorias on Categorias.CategoriaId = Produto.CategoriaId

The Include() statement, as opposed to the lazy load, forces the Entity Framework to fetch the data immediately. That is, a SQL is generated with the joins specified above.

To put conditions on your selection, use Where() :

var produtos = context.Produtos
               .Include(p => p.Fabricante)
               .Include(p => p.Categoria)
               .Where(p => p.Categoria.Nome == "Calçados")
               .ToList();

For compound conditions, just use logical operators, such as && or || :

var produtos = context.Produtos
               .Include(p => p.Fabricante)
               .Include(p => p.Categoria)
               .Where(p => p.Categoria.Nome == "Calçados" && p.Fabricante.Nome != "Adidas")
               .ToList();

Cardinality N

Suppose now that Fabricante is implemented as follows:

public class Fabricante 
{ 
    [Key]
    public Guid FabricanteId { get; set; }

    [Required]
    public String Nome { get; set; }

    public virtual ICollection<Produto> Produtos { get; set; }
}

Just as Produto belongs to Fabricante , Fabricante has several Produtos . The ICollection above specifies this relationship.

To select a Fabricante and its Produtos , use the following sentence:

var fabricantes = context.Fabricantes.Include(f => f.Produtos).ToList();

Persisting Data

To insert a new Produto , the following sequence of steps does this work:

var produto = new Produto 
{
    ProdutoId = Guid.NewGuid(),
    Nome = "Tênis de Corrida",
    Preco = 200,
    Fabricante = context.Fabricantes.SingleOrDefault(f => f.Nome == "Adidas"),
    Categoria = context.Categorias.SingleOrDefault(c => c.Nome == "Calçados")
};

context.Produtos.Add(produto);
context.SaveChanges();

Notice that Ids are not inserted directly. Instead, objects that have all the information that the Entity Framework needs to perform the insertion are populated.

Similarly, an update is done as follows:

var produto = context.Produtos.SingleOrDefault(p => p.Nome == "Tênis de Corrida");

produto.Preco = 250;
context.Entry(produto).State = EntityState.Modified;
context.SaveChanges();
    
19.06.2014 / 20:32