Entity framework loads navigation properties without asking for them
Asked Answered
O

4

8

While working in a project I saw a strange behaviour I cannot understand with the loading of navigation properties.

Here is a small example that reproduces this "problem".

enter image description here

I want to load a Year, without including data of the company(navigation property).

My code:

public static Year GetYear(int id)
{
    using (var context = new testModelContainer())
    {
        var result = context.YearSet.FirstOrDefault(c => c.Id == id);
        //Company test = context.CompanySet.Where(c => c.Id == id).FirstOrDefault();

        return result;
    }
}  

This returns the year I want, without data in the navigation property, but if I uncomment the line and I just execute the line, maybe because I want to know the name of the company or whatever, it authomatically includes the company data into the Company navigation property of the Year.

Any idea how to prevent this behaviour? For security reasons I would want to avoid sendind data of the 'parents'.

I am using EF 6, .NET 4.5.

Olin answered 28/4, 2014 at 12:51 Comment(0)
B
5

This is because you are executing your commands in one context. Entities share information about each other if working within one context.

Thus if you first retrieved the Year and then you retrieve the Company that has a reference to Year entity with the value of previously retrieved Year, your navigation property will be updated automatically and vice versa - Year will have Company property populated.

Bute answered 28/4, 2014 at 12:55 Comment(4)
And how could I 'clean' non-manually-included navigation properties? Should I perform the actions in a different context, and then retrieve my data in a outer context?Olin
@blacai Either remove the navigation property in the model, or indeed use two contexts.Archbishop
@blacai, mind you, if you change that property value manually(say you set it to null), EF will consider this as update of the entity. Next if you call SaveChanges, those will be persisted to database.Bute
Well, the save is not a 'real' problem in this case, because we use very specifics functions to send data to the service and the navigation properties I don't want to save are removed previously.Olin
P
2

A context is a collection of all data that are fetched from the persistence unit.

So here what happens in your example:


Initially:

Context:
****************************
Empty.
****************************

After Fetch Year:

Context:
****************************
1) Year (Year.Company -> null)
****************************

After Fetch Company:

Context:
****************************
1) Year (Year.Company -> 2)  //Refers to second object in the context
2) Company
****************************

After Fetching another Company

 Context:
 ****************************
 1) Year (Year.Company -> 2)  //Refers to second object in the context
 2) Company
 3) Another Company
 ****************************

After Fetching the year that refers to "Another Company"

  Context:
  ****************************
  1) Year (Year.Company -> 2)  //Refers to second object in the context
  2) Company
  3) Another Company
  4) Another Year (Year.Company -> 3) //Refers to third object in the context
  ****************************

Pulchritudinous answered 28/4, 2014 at 13:5 Comment(0)
D
1

Just use .AsNoTracking() on your first entity. Then it will not track entities and it wont load with your desired entity.

Doti answered 10/3, 2021 at 17:50 Comment(0)
P
0

Probably you have lazy loading enabled.

Try to disable it:

context.Configuration.LazyLoadingEnabled = false;

Disable lazy loading by default in Entity Framework 4

Persiflage answered 28/4, 2014 at 12:53 Comment(1)
I already checked this, and turning off lazyloading didn't help.Olin

© 2022 - 2024 — McMap. All rights reserved.