What Difference Does .Asnotracking() Make

What difference does .AsNoTracking() make?

The difference is that in the first case the retrieved user is not tracked by the context so when you are going to save the user back to database you must attach it and set correctly state of the user so that EF knows that it should update existing user instead of inserting a new one. In the second case you don't need to do that if you load and save the user with the same context instance because the tracking mechanism handles that for you.

Does using AsNoTracking() make a difference when only returning fields?

No, it does not since the entities won't be loaded, as evidenced by examining context.Pogs.Local which won't contain the entities whose properties were retrieved through LINQ.

You can check the entities being tracked through DbContext.ChangeTracker. So if you retrieve the entries of the tracker for your Pogs DbSet through context.ChangeTracker.Entries<Pogs>() you'll see that for your first example there are entries tracking the corresponding entities, while for the second example there are none.

Where should AsNoTracking be applied?

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();

Entity framework, What is the difference between AsNoTracking and MergeOption = NoTracking?

AsNoTracking is simply the DbContext/DbSet version (EF 4.1 onwards) of the MergeOption.NoTracking ObjectContext/ObjectSet version (EF 4 and below).

AsNoTracking implementation:

public static IQueryable AsNoTracking(this IQueryable source)
{
Check.NotNull(source, "source");

var asDbQuery = source as DbQuery;
return asDbQuery != null ? asDbQuery.AsNoTracking() : CommonAsNoTracking(source);
}

CommonAsNoTracking implementation:

private static T CommonAsNoTracking<T>(T source) where T : class
{
DebugCheck.NotNull(source);

var asObjectQuery = source as ObjectQuery;
if (asObjectQuery != null)
{
return (T)DbHelpers.CreateNoTrackingQuery(asObjectQuery);
}

var noTrackingMethod = source.GetType().GetPublicInstanceMethod("AsNoTracking");
if (noTrackingMethod != null
&& typeof(T).IsAssignableFrom(noTrackingMethod.ReturnType))
{
return (T)noTrackingMethod.Invoke(source, null);
}

return source;
}

CreateNoTrackingQuery implementation:

public static IQueryable CreateNoTrackingQuery(ObjectQuery query)
{
DebugCheck.NotNull(query);

var asIQueryable = (IQueryable)query;
var newQuery = (ObjectQuery)asIQueryable.Provider.CreateQuery(asIQueryable.Expression);
newQuery.ExecutionStrategy = query.ExecutionStrategy;
newQuery.MergeOption = MergeOption.NoTracking;
newQuery.Streaming = query.Streaming;
return newQuery;
}

Taken from https://entityframework.codeplex.com

AsNoTracking() in entityframework

AsNoTracking() means that the entities will not be cached locally by the ObjectContext instance. This has a few practical benefits:

  1. Memory Usage: Since the ObjectContext isn't referencing the entities after they're returned to you, the Garbage Collector can get rid of them as soon as you're no longer referencing them. Normally, the ObjectContext would need to be disposed before this could happen.

  2. Performance: Since EF doesn't have to try to match every record returned from the database with a local entity in the identity map, your queries might execute slightly faster.

  3. Currency: Since queries return entities materialized directly from the database results and do not rely on a local cache, the returned entities should always reflect the latest values in the database.

  4. Statelessness: Since the entities are not being tracked by ObjectContext, you can continue to use the same ObjectContext instance indefinitely for read-only queries and need not feel constrained by the normal advice regarding having short-lived ObjectContexts.

AsNoTracking() is a good idea if you're only querying entities. It won't work if you need to update them, that is the tradeoff.

About EntityFramework AsNoTracking

No issues with EF. It works because Entry attaches the entity to the context.

See here for more details.

And on this SO specifically about Entry



Related Topics



Leave a reply



Submit