Lazy loading behavior of relations while entity is still new

Posts   
 
    
SanderF
User
Posts: 127
Joined: 11-Dec-2006
# Posted on: 31-Oct-2025 11:06:55   

We are using SelfServicing with version 5.11.3.

Consider this code:

var doc = new DocumentEntity();
var bestanden = doc.Bestanden;

In the 2nd line the property 'doc.Bestanden' is called and executes a query caused by the Self Servicing framework to the database:

exec sp_executesql N'SELECT [dbo].[Bestanden].[BestandID] AS [ID], <<...and many other fields... >>
FROM [dbo].[Bestanden] WHERE ( [dbo].[Bestanden].[BestandDocID] = @p1)',N'@p1 uniqueidentifier',@p1='00000000-0000-0000-0000-000000000000'

This unnecessary in our opinion because the document entity is not saved yet, so there could be no record in the Bestanden table. Even the ID of the DocumentEntity is not set, which is the foreign key in the Bestanden table.

We think the execution of the query would only be useful if the DocumentEntity instance 'doc' has a given 'ID' or maybe simpeler, to check if property IsNew is false. Thus if an entity is still new, then there is no reason to query the database for related entities.

What is your opinion on this issue?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39988
Joined: 17-Aug-2003
# Posted on: 31-Oct-2025 16:53:16   

We don't check if the entity is new, as people use it to fetch related entities for an entity with an id X without first fetching the entity with id X. (like initializing the doc entity with a pk, and then accessing Bestanden). So changing that will be out of the question.

One could argue that there have to be deeper checks if a field is set to be able to lazy load properly, tho this isn't simple, as for the lazy loading code that starts the whole process it's unknown which fields are involved.

SS's lazy loading can trigger unnecessary DB queries, hence it's discouraged to use it.

Frans Bouma | Lead developer LLBLGen Pro
SanderF
User
Posts: 127
Joined: 11-Dec-2006
# Posted on: 04-Nov-2025 10:00:43   

Fetching related entities without fetching the primary entity is very rare in our code base. We would like to have control whether or not the related entities are fetched or not. In PerformMultiEntityLazyLoading() there is this condition:

if (((!GetAlreadyFetchedValueForNavigator(navigator) && EnableLazyLoading) || forceFetch || GetAlwaysFetchValueForNavigator(navigator)) && !IsSerializing && !base.IsDeserializing && !base.InDesignMode)
{
...
}

We would like to have some extra protected virtual method CanPerformLazyLoading(navigator) which we can implement in the specific entities:

if (((!GetAlreadyFetchedValueForNavigator(navigator) && EnableLazyLoading && CanPerformLazyLoading(navigator)) || forceFetch || GetAlwaysFetchValueForNavigator(navigator)) && !IsSerializing && !base.IsDeserializing && !base.InDesignMode)
{
...
}

In the override CanPerformLazyLoading() we can check if the entity is new or not:

protected override bool CanPerformLazyLoading(string navigator)
{
    return !IsNew || (IsNew && Fields["ID"].IsChanged);
}

In our normal cases we don't need the navigator property, but I can imagine situations where we also want to check the navigator name which is going to be fetched.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39988
Joined: 17-Aug-2003
# Posted on: 05-Nov-2025 10:06:28   

Well, I can say up front that we won't make any changes to the lazy loading system. Like I said, you really are encouraged to switch it off and use an adapter style fetching approach or move to adapter altogether.

The one thing you could do here is override the GetMultiBestanden() method in DocumentEntity. (in a partial class, use the 2-classes approach) as that's a virtual method and do the new check in that override. It basically comes down to the same thing as your method and then check the navigator.

Frans Bouma | Lead developer LLBLGen Pro