Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where should AsNoTracking be applied?

I am migrating queries from Linq-to-Sql to EF. To make disabling tracking harder to forget, in Linq-To-Sql I wrote a ConfigureForQuery wrapper function which simply sets ObjectTrackingEnabled to false.
I'd like to continue to use a similar strategy, but based on the information I gathered so far, a global setting for No Tracking is not available. I'd like your opinion on how to best fix my existing queries. Some code:

public class A {
    public int P1 { get; set; } 
    public int P2 { get; set; } 
}
public class B {
    public int P3 { get; set; } 
    public int P4 { get; set; } 
}
public class MyDbContext : DbContext {
    public IDbSet<A> As { get; set; }
    public IDbSet<B> Bs { get; set; }
}

// scenario 1: returning IQueryable of T where IDbSet<T> is defined in a DbContext
public IQueryable<A> Get()
{
    var query =
        from a in db.As
        join b in db.Bs
             on a.P1 equals b.P3
        where b.P4 > 50
        select a;
    return query;
}

Q1: where and how do I apply AsNoTracking?
Q2: In this case, do I need to apply AsNoTracking to Bs?

// scenario 2: returning IQueryable of T where IDbSet<T> is NOT defined in a DbContext
public class C {
    public int P1 { get; set; } 
    public int P4 { get; set; } 
}
public IQueryable<C> Get()
{
    var query =
        from a in db.As
        join b in db.Bs
             on a.P1 equals b.P3
        where b.P4 > 50
        select C { P1 = a.P1, P4 = b.P4};
    return query;
}

Q3: Do I need AsNoTracking in this case?

Thanks for your help.

like image 517
Candy Chiu Avatar asked Oct 19 '25 09:10

Candy Chiu


1 Answers

In the first scenario, you can simply apply AsNoTracking to the result of the query:

public IQueryable<A> Get() {
  var query =
    from a in db.As
    join b in db.Bs
         on a.P1 equals b.P3
    where b.P4 > 50
    select a;

  return query.AsNoTracking();
}

In the second scenario, since you are returning something not in the DbContext then its not tracked anyway so you don't need to do anything.

You can inspect the change tracker after querying to see what's being tracked and what's not.

var tc = db.ChangeTracker.Entries().Count();
like image 75
Alaa Masoud Avatar answered Oct 22 '25 02:10

Alaa Masoud



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!