EF 5 Release Candidate 1 — Filtro no Include<>

Fulvio Cezar Canducci Dias
2 min readOct 7, 2020

Um recurso que é presente nessa nova fatura é o filtro na relação que existem entre entidades, isso é um fator que antigamente não tinha e causava uma insatisfação na turma do desenvolvimento, claro tinha pacotes auxiliares que resolviam esse problema, mas, nada é melhor do que já existir isso por padrão no Entity Framework Core 5.

Um exemplo para exemplificar a facilidade de utilizar esse recurso:

Entidades Items e Sales relacionamento 1 Item tem ou não vários Sales:

public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Sales> Sales { get; set; }
}
public class Sales
{
public int Id { get; set; }
public decimal Value { get; set; }
public int ItemId { get; set; }
public Item Item { get; set; }
}

Configurando o DbContext:

  • Mapeando as entidades
public sealed class ItemMap : IEntityTypeConfiguration<Item>
{
public void Configure(EntityTypeBuilder<Item> builder)
{
builder.ToTable("Item");
builder.HasKey(c => c.Id);
builder.Property(c => c.Id)
.UseIdentityColumn();
builder.Property(c => c.Name);
builder.HasMany(c => c.Sales)
.WithOne(c => c.Item)
.HasForeignKey(c => c.ItemId)
.HasPrincipalKey(c => c.Id);
}
}
public sealed class SaleMap : IEntityTypeConfiguration<Sales>
{
public void Configure(EntityTypeBuilder<Sales> builder)
{
builder.ToTable("Sale");
builder.HasKey(c => c.Id);
builder.Property(c => c.Id)
.UseIdentityColumn();
builder.Property(c => c.Value)
.IsRequired();
builder.HasOne(c => c.Item)
.WithMany(c => c.Sales)
.HasForeignKey(c => c.ItemId)
.HasPrincipalKey(c => c.Id);
}
}
  • Configuração do DbContext:
public class DatabaseSource : DbContext
{
public DatabaseSource(DbContextOptions<DatabaseSource> options)
:base(options)
{
}
public DbSet<Sales> Sales { get; set; }
public DbSet<Item> Item { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new SaleMap());
modelBuilder.ApplyConfiguration(new ItemMap());
}
}

Isso é nada de novidade, mas, fica como demonstração e reforço da configuração de entidades no Entity Framework Core 5, mas, vamos para o que realmente importa, o exemplo da expressão a ser utilizado, que é filtrado todos os itens e suas vendas onde essas vendas tem o valor igual a 200.

using (DatabaseSource db = new DatabaseSource(options))
{
var items = db.Item.AsNoTracking()
.Include(x => x.Sales.Where(c => c.Value == 200)) // filtro
.ToImmutableList();
}

e verificando a saída em SQL no SqlProfiler:

SELECT [i].[Id], [i].[Name], [t].[Id], [t].[ItemId], [t].[Value]
FROM [Item] AS [i]
LEFT JOIN (
SELECT [s].[Id], [s].[ItemId], [s].[Value]
FROM [Sale] AS [s]
WHERE [s].[Value] = 200.0
) AS [t] ON [i].[Id] = [t].[ItemId]
ORDER BY [i].[Id], [t].[Id]

e é perceptível o filtro na relação onde o valor é igual à 200.

Resumo: agora o método Include pode ser criado expressão IQueryable e isso é traduzido para a SQL compilado e enviado para o seu banco de dados, filtrando as informações.

Projeto exemplo:

Referencias

--

--

Fulvio Cezar Canducci Dias

Bacharel em Sistemas de Informação, MTAC (Multi-Plataform Technical Audience Contributor-Microsoft), BackEnd C# e PHP e Developer Web