Generics with DTO and Persistence classes

Posts   
 
    
Posts: 4
Joined: 22-Nov-2021
# Posted on: 21-Feb-2023 22:57:44   

Hi,

Our LLBLGEN Pro version is 5.7 and we are using the adapter pattern.

We are currently using generics in order to create a caching layer in front of the Entity Type. We recently found out that this causes issues due to the fact that the Entity should not be cached, per one of the websites documentations.

We were looking to use DTO's instead in order to cache rather than an Entity, but realized that the templates generating DTO's have no base class and that the Persistence classes are DTO object specific.

So I wanted to ask, are there any extensions or templates that I need to look at to enable a feature that allows us to use DTO objects as if they were first class citizens of the framework, rather than the Entity?

I'm providing a very small set of code here, all from the same class: (I am withdrawing some parts of the code so as to obfuscate our IP, so I hope it comes across well enough)

public class DataCache<TEntity> where TEntity : EntityBase2, IEntity2

Then to get an item from the adapter, we will use one of the Fetch functions, here is an example that has been simplified down:

public TEntity FetchEntityByPK(..)
{
   ...
                          GetFromDB<TEntity>()
   ...
}

private static TItem GetFromDB<TItem>(TItem itemIn)
{
    ....
                        adapter.FetchEntity((IEntity2)itemIn);
                        value = itemIn;
                        return value;
    ....
}

Since the Persistence classes that are tied to a DTO have a very specific name, e.g. ProjectToJobDto in the case of a Job table, i've hit a dead end with where the code currently is at the moment.

Also, my assumption, since the Entity is also being used within the Persistence classes within said ProjectToJobDto, e.g.:

public static ABP.Db.DtoClasses.JobDerivedDto ProjectToJobDerivedDto(this ABP.Db.EntityClasses.JobEntity entity)

is that an Entity is a first class citizen and the DTO is a byproduct of wanting a disconnected POCO.

So that's where my question lies, is if I can take this further with the hopes that perhaps I have missed something and that there are a set of other libraries or extensions that I do not know about that could help us bridge the gap of replacing the Entity for a DTO by using generics.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 22-Feb-2023 09:41:50   

Have you looked into resultset caching? https://www.llblgen.com/Documentation/5.7/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/gencode_resultsetcaching.htm

This will materialize new entity objects around cached resultsets so it won't go to the database if the query is the same. This might remove the need for the caching layer altogether?

Frans Bouma | Lead developer LLBLGen Pro
Posts: 4
Joined: 22-Nov-2021
# Posted on: 22-Feb-2023 19:31:29   

Thanks Otis, I will look into that to see if it would fit in with our needs and the way our code is currently implemented.

But with that aside, I'm guessing my assumption then is correct that there isn't a way forward with the DTO's?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 23-Feb-2023 09:23:29   

RamonHenares wrote:

Thanks Otis, I will look into that to see if it would fit in with our needs and the way our code is currently implemented.

But with that aside, I'm guessing my assumption then is correct that there isn't a way forward with the DTO's?

DTOs are projections of entity graphs, and can contain denormalized fields. So they're not first class citizens of the entity model as they're merely a projection of that entity model's elements and are usually used in a readonly fashion (e.g. you return them from a service).

Caching entity instances is ok as long as you use them either in a readonly fashion or on the same thread. So the core issue really is: why are you caching entities? If it's to avoid a very slow fetch of data, then the resultset caching might already help a great deal. If it's done because there's an assumption fetching data from the database is 'slow' then it likely isn't needed, as fetching data in our framework is very very fast.

But really, for readonly purposes, caching entity instances is fine. I doubt you're caching everything, right? The designer allows you to specify if an entity can be altered (on the mappings tab, 'allowed actions'). You could e.g. create new readonly entities mapped onto the same tables and specify that only 'retrieve' is allowed for these entities, so you can't persist them. You could cache these and use them in readonly logic where you use them in a readonly scenario.

Frans Bouma | Lead developer LLBLGen Pro