What is the advantage of using the Set<> method?

Asked

Viewed 261 times

14

What is the advantage or difference in using the method Set<> and I can do the same thing without him 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();

3 answers

10

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

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

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

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

Use:

var teste = PrimeirosDez<Aluno>();
var teste2 = PrimeirosDez<Professor>();
  • Cigado, but wasn’t the T set with a specific type to be used? As in the example you gave, T expects a class that can be Student or Teacher?

  • You can limit T using a syntax like this: public IEnumerable<T> PrimeirosDez<T>() where T: class, IMinhaInterface { ... }

8


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

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

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

The two methods do practically 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 enunciation of this method, you are not aware of the context Dbsets, so the way to load the data is by using generic Dbset. Below 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();
    }
}

6

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

This method was created for situation where you don’t know what kind of data you are working with, i.e., when writing generic code:

contexto.Set<T>();

I put in the Github for future reference.

I know you have some leverage when you’re using Migrations but I don’t know in depth.

  • bigown, but with generic I do not specify a certain type, other than Collections?

  • 3

    So when you are writing a generic code you will use a "variable type", ie the T. Then when using this code you wrote there you will pass the type you are using to be replaced on T. But then you won’t be using the type (in your example Aluno) in the Set<> and yes in its code. That is, the Set<> serves only to produce generic code and not to consume generic codes. If you know you will always use Aluno does not produce a generic code. Are you creating a generic code? I don’t think so use the contexto.Alunos.Remove(aluno) and don’t worry

Browser other questions tagged

You are not signed in. Login or sign up in order to post.