Load Entities AsNoTracking() with navigation properties, without specifying includes

11,108

The simple answer is no. For normal tracking queries, the state manager is used for both identity resolution (finding a previously loaded instance of a given entity and using it instead of creating a new instance) and fixup (connecting navigation properties together). When you use a no-tracking query it means that the entities are not tracked in the state manager. This means that fixup between entities from different queries cannot happen because EF has no way of finding those entities.

If you were to use Include with your no-tracking query then EF would attempt to do some fixup between entities within the query, and this will work a lot of the time. However, some queries can result in referencing the same entity multiple times and in some of those cases EF has no way of knowing that it is the same entity being referenced and hence you may get duplicates.

I guess the thing you don't really say is why you want to use no-tracking. If your tables don't have a lot of data then you're unlikely to see significant perf improvements, although many factors can influence this. (As a digression, using the ObservableCollection returned by .Local could also impact perf and should not be necessary if the data never changes.) Generally speaking you should only use no-tracking if you have an explicit need to do so since otherwise it ends up adding complexity without benefit.

Share:
11,108

Related videos on Youtube

Rand Random
Author by

Rand Random

Updated on September 15, 2022

Comments

  • Rand Random
    Rand Random over 1 year

    I would like to know if the following scenario is possible with Entity Framework:

    I want to load several tables with the option AsNoTracking since they are all like static tables that cannot be changed by user.

    Those tables also happen to be navigation property of others. Up till now I relied on the AutoMapping feature of the Entity Framework, and don't use the .Include() or LazyLoading functionality.

    So instead of:

    var result = from x in context.TestTable
              .Include("ChildTestTable")
    select x;
    

    I am using it like this:

    context.ChildTestTable.Load();
    context.TestTable.Load();
    var result = context.TestTable.Local;
    

    This is working smoothly because the application is so designed that the tables within the Database are very small, there won't be a table that exceeds 600 rows (and that's already pretty high value in my app).

    Now my way of loading data, isn't working with .AsNoTracking(). Is there any way to make it working?

    So I can write:

    context.ChildTestTable.AsNoTracking().List();
    var result = context.TestTable.AsNoTracking().List();
    

    Instead of:

    var result = from x in context.TestTable.AsNoTracking()
              .Include("ChildTestTable")
    select x;
    

    So basically, I want to have 1 or more tables loaded with AutoMapping feature on but without loading them into the Object State Manager, is that a possibility?