Navigation properties return null when lazy loading is disabled

Shortly speaking:

Is there a way to make an EF exception if the code accesses the navigation property and the requested data is not loaded into memory and lazy loading is disabled?

Longer:

I am using Entity Framework 4 (model first) and have disabled lazy loading. Previously, if I run something like the following, the code will work fine, but it will be slow, since every call is for the client. As a result, a new SQL query was executed:

int totalValue = 0; foreach(var customer in efContext.Customers) foreach (var order in customer.Orders) totalValue += order.Value; 

I wanted to completely disable lazy loading in order to prevent such code from appearing in the code base I'm working on. What I would like to do is that when the client executes the code. Orders, an exception should be thrown indicating something in the "Entity not loaded" lines. Lazy loading is off. "But instead, the list of orders is simply empty because orders are not loaded.

I feel that this behavior can also be problematic, just differently than lazy loading. A developer who has been instructed to verify that each client has a contact can write something like the following:

 if (customer.Contact != null) throw new BlablablaException("Customer lacks contact"); 

But with lazy loading disabled, the client. The contact will always be zero, and the developer might think that his code is working correctly. Of course, he must do his job correctly and check both scenarios (contact the existing one, contact does not exist), but it would be much clearer if an exception were thrown.

In my opinion, it seems strange that the Entity Framework does not throw an exception if I try to access data that is not available, and instead just returns an empty list.

Is there any explanation for this behavior? And is there any way to make an EF throw exception when calling the navigation property and non-avaialble data?

+4
source share
1 answer

You can check each entry to make sure it is uploaded.

If this is a collection:

 model.Entry(customer).Collection(c => c.Customers).IsLoaded 

If this is not a collection:

 model.Entry(customer).Reference(c => c.Customer).IsLoaded 

However, I think it would be better if you just eagerly loaded your collection before iterating through it, ensuring that the collections are loaded and not worry about whether the collection is loaded or not:

 foreach(var customer in efContext.Customers.Include(c => c.Orders)) 
0
source

Source: https://habr.com/ru/post/1435545/


All Articles