EF 5 Release Candidate 1 — Filtro no Include<>
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