What is the advantage of using the Set method?

13

What is the advantage or difference in using the Set<> method, and can I do the same without it as in alternative 2?

Alternative 1

var aluno = contexto.Alunos.First(x => x.Id == entidade.Id);
contexto.Set<**Aluno**>().Remove(aluno);
contexto.SaveChanges();

Alternative 2

var aluno = contexto.Alunos.First(x => x.Id == entidade.Id);
contexto.Alunos.Remove(aluno);
contexto.SaveChanges();
    
asked by anonymous 22.09.2015 / 00:39

3 answers

6

The choice between using the DbContext.Set or the DbSet object instantiated in the Context depends on the use and how you work with context.

The DbContext.Set<T> method returns using the Generics DbSet of the context, evaluating the type parameter of the method signature. This demonstrates that when we call it, it performs a "lookup" on context objects and "loads" the data of that type into the Context.

The DbSet<T> object of the Context is an object that in theory is loaded when you instantiate the Context and this object is preloaded for use within the application.

The two methods do pretty much the same thing, but at different times. Another factor that can influence the use of one or the other is the exposure of objects between different libraries and namespaces. If you pass your context to a method using the DbContext class in the statement of this method, you are not aware of the context DbSets, so the way to load the data is by using the generic DbSet. Here is a small example:

using System;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Collections.Generic;

public class Contexto : DbContext
{
    public DbSet<Aluno> Alunos { get; set; }

    public Contexto()
    {
        Configuration.LazyLoadingEnabled = true;
        Configuration.AutoDetectChangesEnabled = false;
        Configuration.ValidateOnSaveEnabled = false;
    }

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

public class Aluno
{
    public String Nome { get; set; }
}

public class Program
{    
    public List<Aluno> GetAlunos(DbContext ctx)
    {
        // O compilador não irá reconhecer se chamarmos o DbSet ctx.Alunos.
        return ctx.Set<Aluno>().ToList();
    }

    public List<Aluno> GetAlunos2(Contexto ctx)
    {
        return ctx.Alunos.ToList();
    }
}
    
22.09.2015 / 14:04
10

The advantage actually exists when you want to implement generic behavior in some function of your own.

For example, you want to write a method that brings only the first 10 records of any DbSet . You can do this as follows:

public IEnumerable<T> PrimeirosDez<T>() {
    return contexto.Set<T>().Take(10).ToList();
}

That is, implement an extension to the context that brings the first 10 elements to any DbSet .

Usage:

var teste = PrimeirosDez<Aluno>();
var teste2 = PrimeirosDez<Professor>();
    
22.09.2015 / 00:51
6

In this specific case there really is no advantage. Use the second form.

This method was created for a situation where you do not know what type of data you are working with, that is, when you are writing generic code:

contexto.Set<T>();

I know it has some advantage when using migrations but I do not know in depth.

    
22.09.2015 / 00:52