3

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.

Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438

2 Answers2

3

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:

trailmax
  • 34,305
  • 22
  • 140
  • 234
  • @paddy Okej, so we have two high-ranked users presenting, as it appears to me, two diagonally opposite statements. Comment? – Konrad Viltersten Oct 08 '15 at 15:34
  • Yes, I'm looking into the other answer as well - new thing to me. I'll update my answer once I have more. – trailmax Oct 08 '15 at 15:35
  • Don't. Your answer is a footprint of your (as I assume) considerable experience. It's of high value even if it's not entirely correct. It coule be that the hack was only relevant in older version of EF. Also, it could be used for hiding performance issues at other places in the code. – Konrad Viltersten Oct 08 '15 at 15:40
  • Oh, too late - already done the update with links to actual source code. For a moment I questioned my sanity -) – trailmax Oct 08 '15 at 15:49
  • For thoroughness +1. But why are you questioning your sanity? – Konrad Viltersten Oct 08 '15 at 19:06
  • I referred to the other answer in the context of this question - it made me question the way I've used `AsNoTracking` in multiple places. – trailmax Oct 08 '15 at 19:08
  • You might want revise the links. I only get anywhere with the last one. The others produce errors. – Konrad Viltersten Oct 08 '15 at 19:09
  • Good point - fixed the second, but first one contains backtick and that is getting encoded by SO. So replace `%60` in the url with `. Or short-link might work for the first link. – trailmax Oct 08 '15 at 19:23
  • By the way, there are a lot more places where `AsNoTracking` is mentioned, but the place where it is processed - the last link. – trailmax Oct 08 '15 at 19:26
0

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.

Community
  • 1
  • 1
Paddy
  • 33,309
  • 15
  • 79
  • 114
  • 1
    I think you misinterpret the question. The OP is worried if `AsNoTracking` has effect on other queries, where `AsNoTracking` is not applied. Can you please look into this again, as I start to be worried if I've used this method for a long time in an incorrect way. – trailmax Oct 08 '15 at 15:53
  • @trailmax - OP asked if there were any issues (in general) that might occur when this was removed. This is a possible issue (and is something that I have encountered and changed code in order to avoid using No tracking). You sound like you might have a different question? While this won't affect the second query results, it might have a downstream impact as the state of the results returned will be slightly different (i.e. not tracked). – Paddy Oct 09 '15 at 08:24