Konrad Viltersten
Konrad Viltersten

Reputation: 39118

Is there any hidden functionality behind AsNoTracking()?

I'm working with a large project (with a number of different cooks making the soup, across the years passing by) and just discovered the following code.

private IEnumerable<string> SomeSome()
{
  using(DataModel context = DataModel())
  {
    context.SomeEntityName.AsNoTracking();
    ...
    return context.SomeEntityName
      .Where(entity => true)
      .Select(entity => String.Empty);
  }
}

Now, I've tripple-checked the AsNoTracking method and it's clearly said to return a queryable object that has no business with the EF's tracking facilities. A sort of "fire and forget" for ORM, so to speak.

Noting that:

  1. we don't store the value nor do anything with the contents of the returnee
  2. we obtain a new (and apparently trackable) set of objects to do stuff with

I want to remove the line. However, being modest (i.e. scared poo-lessly to damage the system), I'm cautious before deleting anything. Is there any implicit changes within the context of mine that might affect the second retrieval of the entities?

I haven't found any info on it - neither in favor of or against that theory. Also, I haven't found documentation for any other version of EF than 5.0 (as the link above shows) but we're using EF 6.1.3 and I understand that the method in question's been around in EF 4 as well.

Upvotes: 3

Views: 716

Answers (2)

Paddy
Paddy

Reputation: 33857

If you serialize this object, you may find that you run into issues if you have many-to-many relationships defined. The AsNoTracking() call may have been put in place to work around this, as here:

Serialization of Entity Framework objects with One to Many Relationship

In all fairness this is a bit of a hack and can lead (as you have just noticed) to people wondering why this was called when maintaining. If this is being serialized, it may be better to have a separate serializable DTO rather than passing the context object itself.


I would also note that there has been some discussion about turning off tracking to increase performance. Depending on what you are hitting, you can get (apparently) significant performance improvements when disabling tracking.

Upvotes: 0

trailmax
trailmax

Reputation: 35106

If that line of code is exactly as in your project, then there is no change.

context.SomeEntityName.AsNoTracking();

this ^^^ returns queryable object that is not saved anywhere. If you remove that line, there will be no difference to the queries down the line.

Upd I have looked through the source code of EF. And as far as I can see AsNoTracking() does not change the state of DbContext object you are working with. So if this method was called on one query, it should not affect the execution of other queries in a slightest. If it does - it is a bug in EF and should be reported. In multiple places in my project I have same dbContext queries with tracking and without. And everything works as expected.

Sources:

Upvotes: 3

Related Questions