Object Caching/Persistence - Application Singleton - And other Qs

Posts   
 
    
MatthewM
User
Posts: 78
Joined: 26-Jul-2006
# Posted on: 26-Jul-2006 20:41:05   

I have several questions actually. I am going to put them all here and cross my fingers.

1) I need to persist/cache some static and near static data. I would like to have LLBL generate singleton classes for these, but I suppose I can just wrap the relevant entity/collections myself. Q: What is the best persistence implementation in ASP.NET? Intuitively I thought I would just use the asp cache object and store the ref to my singleton. Then all updates to the relevant entity always go through the singleton so that its data is always up to date. Am I overcomplicating this? Is there something in LLBL that I am missing which would make this easier? How are others tackling this?

2) I have several entities that reference themselves. I need a collection pattern to load all upstream parent records until the parent is null. Is there a simple way to do this?

3) I am having trouble with target-per-entity. I cannot figure out how to create these. The context menu "construct ..." does nothing with my entities. My scenario: The data model has X# tables that reference a core/root table. I want that core/root table to be a base class that the other X# resulting entities inherit from. TargetPerEntity is the right idea? How do I manually create this inheritance scenario if the "construct ..." context menu does not do anything?

4) I want to insert custom authentication code before every load/save. What is the best way to do this? Modify the templates I would guess. This seems like a chore not being familiar with the templates, but the thought of overriding each method after the fact is even more silly eh.

5) Comment: I was having trouble discerning differences and when to use selfservicing vs adapter. After much digging I found the doc page: Concepts - Templates and Template groups. Very helpful summary information at the bottom.

Thank you for your responses.

Posts: 1268
Joined: 10-Mar-2006
# Posted on: 26-Jul-2006 20:51:11   

1) I am interested in the comments on this also. I need to implement some caching, but have not done it yet.

2) The book http://www.lulu.com/content/174470 has an example of just this - and I think the answer is even in the free preview, although for $7.35, you might want to buy and support the Author/Community. EDIT The book is now free for download.

3) If the menu doesn't work, review your relationships and table design. If this is not right, it will not work. The base table should have a PK. The child table should have the PK of the base table in it - it should also be marked as a PK and have a FK relationship to the base table.

4) There is an add-on template available for download that will insert a common base class for all Entities. You can then add that code in that one base class for all others to inherit. Check the download section.

5) What did you choose and why?

MatthewM
User
Posts: 78
Joined: 26-Jul-2006
# Posted on: 26-Jul-2006 21:49:46   

WayneBrantley wrote:

2) The book http://www.lulu.com/content/174470 has an example of just this - and I think the answer is even in the free preview, although for $7.35, you might want to buy and support the Author/Community. EDIT The book is now free for download.

Thanks, I'll check that out

WayneBrantley wrote:

3) If the menu doesn't work, review your relationships and table design. If this is not right, it will not work. The base table should have a PK. The child table should have the PK of the base table in it - it should also be marked as a PK and have a FK relationship to the base table.

Ok, so it has to be designed a true 1:1? Unfortunately for other reasons I cannot do that without adding an extra table in the middle which would be just a lot of extra work. So, there is no other way to get LLBL to generate the inheritance if the Schema is setup up as a 1:m even though it really is conceptually a 1:1?

It would be nice if there was a way in LLBL to override the perceived relationship from a 1:m to 1:1 so that the inheritance would work.

WayneBrantley wrote:

4) There is an add-on template available for download that will insert a common base class for all Entities. You can then add that code in that one base class for all others to inherit. Check the download section.

Worth looking at further, thanks again. Essentially then the generated entity code would look like this? Entity:

public override Save(params)
{
  base.Save(); // performs my code, which throws an exception if no op

  // std entity save code...
}

WayneBrantley wrote:

5) What did you choose and why?

Selfservicing for every reason listed under: "When to use SelfServicing". Of course I kind of grumble for future projects which will be distributed and thus need adapter model. I am not looking fwd to the extra coding work to regain related data loads (assuming I am reading examples right).

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 27-Jul-2006 02:23:24   

on 1 You may look into the Context provided by LLBLGen. This may do what you are needing and is explained in detail under Generated code - Using the context, SelfServicing

on 4

Worth looking at further, thanks again. Essentially then the generated entity code would look like this? Entity: Code: public override Save(params) { base.Save(); // performs my code, which throws an exception if no op

// std entity save code... }

It looks as though you may want to validate the entity before saving it. If this is the case then you should look in the manual under Generated code - Validation per field or per entity. OnValidateEntityBeforeSave may be a candidate for your example.

Posts: 1268
Joined: 10-Mar-2006
# Posted on: 27-Jul-2006 04:25:58   

on 1 You may look into the Context provided by LLBLGen. This may do what you are needing and is explained in detail under Generated code - Using the context, SelfServicing

The manual specifically states:

It is not necessary to use a Context object in your application, for example in state-less environments like ASP.NET, it's not of much use.

and

The Context objects don't act as a cache which is used to prevent database activity. Every query is still executed on the database.

Or am I missing something?

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 27-Jul-2006 07:22:16   

on 1

I think we could just save the object in the ASP.NET Application object. And use it from there.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 27-Jul-2006 11:04:15   

Context != cache. It's a mechanism to get unique instances for entity containers (== instances of entity classes).

A cache is more sophisticated: it has a mechanism to mark elements in the cache as stale etc. The context doesn't have that.

The ASP.NET cache is OK for this, though you can also use the Application object as Walaa suggested. Just be sure to load the application object data in the Application_begin request event handler, so the object is filled before the first session starts.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 27-Jul-2006 11:12:17   

MatthewM wrote:

3) I am having trouble with target-per-entity. I cannot figure out how to create these. The context menu "construct ..." does nothing with my entities. My scenario: The data model has X# tables that reference a core/root table. I want that core/root table to be a base class that the other X# resulting entities inherit from. TargetPerEntity is the right idea? How do I manually create this inheritance scenario if the "construct ..." context menu does not do anything?

Target-per-entity requires a 1:1 pk-pk relation between supertype and subtype.

Ok, so it has to be designed a true 1:1? Unfortunately for other reasons I cannot do that without adding an extra table in the middle which would be just a lot of extra work. So, there is no other way to get LLBL to generate the inheritance if the Schema is setup up as a 1:m even though it really is conceptually a 1:1?

I don't see how a 1:n relation can be conceptually a 1:1... If you want a 1:1, make it a 1:1 relation. It can't be a 1:n relation because that could give multiple subtype rows per subtype INSTANCE. You can't share a SUPERTYPE row among multiple subtype instances!

Inheritance isn't always what you want. Target-per-entity mapping requires joins for a lot of queries you do. This might be great for some purposes, but for others it might be overkill. So choose your setup wisely.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 1268
Joined: 10-Mar-2006
# Posted on: 27-Jul-2006 16:22:59   

Context != cache. It's a mechanism to get unique instances for entity containers (== instances of entity classes).

A cache is more sophisticated: it has a mechanism to mark elements in the cache as stale etc. The context doesn't have that.

The ASP.NET cache is OK for this, though you can also use the Application object as Walaa suggested. Just be sure to load the application object data in the Application_begin request event handler, so the object is filled before the first session starts.

Otis, To be clear - even putting a context object in the ASP.NET cache would not work - as all queries are re-executed anyway. (Does SetExistingEntityFieldsInGet turn that off?) Anyway, the context works with Entities and for my caching needs, I also need EntityCollections cached.

Regarding caching and LLBLGenDataSource - manual says:

There's no support for the ASP.NET cache to store the data instead. This is due to the fact that it's hard to specify a true unique key for the data to make caching really useful.

My question is, what does the Microsoft ObjectDataSource do, as it supports this feature? What might be nice is to let the LLBLGen user supply the key.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 27-Jul-2006 19:17:43   

WayneBrantley wrote:

Regarding caching and LLBLGenDataSource - manual says:

There's no support for the ASP.NET cache to store the data instead. This is due to the fact that it's hard to specify a true unique key for the data to make caching really useful.

My question is, what does the Microsoft ObjectDataSource do, as it supports this feature? What might be nice is to let the LLBLGen user supply the key.

It's using dirty internal code, a very big cache manager which is an internal class, so I can't use it. It also uses a couple of shortcuts I can't use, because filters and the like are more sophisticated than with an objectdatasource. The filter is part of the key in objectdatasource, but that's not possible for predicates (could lead to dupes, due to the non-textual nature of the object).

Frans Bouma | Lead developer LLBLGen Pro
MatthewM
User
Posts: 78
Joined: 26-Jul-2006
# Posted on: 28-Jul-2006 17:30:15   

Thanks all - I am quite pleased and surprised with the volume & speed of replies on the board. This information was quite helpful.