Change a Generic Repository method to return with Asnotracking - EF Core

Asked

Viewed 96 times

0

I have a generic repository, in particular the method GetbyId, in which I wish to change it to return a result with AsNoTracking or not 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);
        }
}

2 answers

0

Based on that response from the OS.

The Method Find() does not possess the AsNoTracking(), but you can change his status 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;
}

0


The find method makes no sense to be used with Asnotracking, since, by its description, it is informed that it is first checked whether the object is being tracked:

Finds an Entity with the Given Primary key values. If an Entity with the Given Primary key values is being tracked by the context, then it is returned immediately without making a 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.

A possible alternative to your case is to use an Entity class as a basis:

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

And its entities inherit from that class.

In your repository, you change the Generic Tentity Constraint 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...
}

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

Using find as in the other answer, causes the EF to check in tracking if the entity is there, click from the database, cache, only to remove (changes the status to Detached). As I explained, it will cause the EF to not even try to add the entity in tracking.

Browser other questions tagged

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