4

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.

Candy Chiu
  • 6,579
  • 9
  • 48
  • 69

1 Answers1

5

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();
Alaa Masoud
  • 7,085
  • 3
  • 39
  • 57
  • Remember to add using System.Data.Entity; for the AsNoTracking() extension to be available on an IQueryable – Stewart Feb 02 '16 at 22:55