Change a generic repository method to return with AsNoTracking - EF Core

0

I have a generic repository, in particular, the GetbyId method, in which I want to change it to return a result with AsNoTracking or No, as needed. How do I do this?

My Interface:

TEntity GetById(int id, bool @readonly = false); 

My Generic Repository:

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        protected readonly RetaguardaContext Db;
        protected readonly DbSet<TEntity> DbSet;

        public Repository(RetaguardaContext context)
        {
            Db = context;
            DbSet = Db.Set<TEntity>();
        }       
        public virtual TEntity GetById(int id, bool @readonly = false)
        {
            return DbSet.Find(id);
        }
}
    
asked by anonymous 23.08.2018 / 18:43

2 answers

0

The find method is meaningless to be used with AsNoTracking, since it is informed by the description that it is first checked if the object is being tracked:

  

Finds an entity with the given primary key values. If an entity with   the given primary key values are being tracked by the context, then it   is returned immediately without request to the database.   Otherwise, a query is made to the database for an entity with the   given primary key values and this entity, if found, is attached to the   context and returned. If no entity is found, then null is returned.

One possible alternative to your case is to use an Entity class as a base:

public class Entidade 
{
    public int ID { get; set;}
}

And their entities inherit from this class.

In your repository, you change the constraint of generic TEntity to be an Entity

public class Repository<TEntity> : IRepository<TEntity> where TEntity : Entidade 
{
    // construtores e propriedades... 

    public virtual TEntity GetById(int id, bool @readonly = false)
    {
        if (@readonly) 
            return DbSet.AsNoTracking().SingleOrDefault(x => x.ID == id);

        return DbSet.Find(id);
    }

    // seus outros métodos...
}

So all your generic methods will have access to the ID property.

Using find as in the other response, causes EF to check in tracking if the entity is there, load it from the database, cache, only to remove (change status to detached). In the way I've explained, it will make EF not even try to add the entity in tracking.

    
23.08.2018 / 19:32
0

Based on this OS response .

Method Find() does not have AsNoTracking() , however you can change its state to Detached , which is the equivalent.

Your code would look something like this:

public virtual TEntity GetById(int id, bool @readonly = false)
{
    var entity =  DbSet.Find(id);

    if(@readonly)
        Context.Entry(entity).State = EntityState.Detached;

    return entity;
}
    
23.08.2018 / 19:07