reference to object vs copy of object

Posts   
 
    
arschr
User
Posts: 894
Joined: 14-Dec-2003
# Posted on: 13-Nov-2004 14:26:16   

Something that you said in another thread on turning entity collections into datatasets raised a question in my mind.

You said something about losing the hierarchy when converting to a dataset.

Let's say I have a table of items, they have a relation to a item category table on categoryid. I have 2 items that have the same item category key, so in the database they refer to the same row in the item category table.

Now I want to express these into a entity collection of items, each item entity in this collection get's it's related item category entity. In the database they are the same row, In my item entities are they referencing the same object or two objects that look the same but are 2 independant objects? I think the later. If that is true, what are the reasons for not having both refer to the same item category object? If they did you would maintain the graph of relationships that are expressed in the database rather than converting it into a tree in the llbgen layer.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 13-Nov-2004 15:32:04   

arschr wrote:

Something that you said in another thread on turning entity collections into datatasets raised a question in my mind.

You said something about losing the hierarchy when converting to a dataset.

Let's say I have a table of items, they have a relation to a item category table on categoryid. I have 2 items that have the same item category key, so in the database they refer to the same row in the item category table.

Ok simple_smile

Now I want to express these into a entity collection of items, each item entity in this collection get's it's related item category entity. In the database they are the same row, In my item entities are they referencing the same object or two objects that look the same but are 2 independant objects? I think the later.

Correct, if you fetch them one by one. If you fetch them by a prefetch path, they're the same object. However you shouldn't rely on the fact they're the same object. What you're referring to is uniquing, something that's not implemented yet, because it is very hard to make it work for 100% in 100% of the cases. For example a webfarm will break this, also a service on 2 machines with a load balancer will not work. Also see below.

If that is true, what are the reasons for not having both refer to the same item category object? If they did you would maintain the graph of relationships that are expressed in the database rather than converting it into a tree in the llbgen layer.

The reality of your application is the application state which is the persistent storage. At least, that's the only reality that is true for all code in your application. Uniquing, one entity's data in just one object and every reference to that entity gets a reference to that same object, is not possible to implement, at least not on .NET. I can give you a long list of examples, but I think it's pretty obvious why it can't work. (dreaded example: desktop application on 20 boxes targeting the same database)

Uniquing can only work in the same transaction, that is: you create an adapter object, you fetch some data and keep that adapter around, and after some work you save the entities again. To have unique objects in all the code using that adapter, it's not that hard to setup a cache in the adapter class. This is planned.

However, as soon as you leave the adapter object you used to fetch an entity and try to fetch a set of related objects later, with another adapter instance, this is not working. Any asp.net application suffers from this, unless it uses a BL service without a loadbalancer.

So to rely on uniquing, it has to be 100% reliable. As I couldn't find a way to make that reliable (as teh only way to make it reliable requires a central cache service which looks exactly the same as sqlserver in interfacing/security etc. i.o.w. pretty re-inventing the wheel) I didn't offer it.

Frans Bouma | Lead developer LLBLGen Pro
arschr
User
Posts: 894
Joined: 14-Dec-2003
# Posted on: 13-Nov-2004 17:32:33   

I understand that there are issues with this. Such when are things really the same and when are they not (with out getting into deep philosophy).

But if you provide a way to transform a set of entities and collections into a dataset (which I think would be good) you would have to deal with this. As a practical matter if items from the database have a timestamp field and multiple entities came from the "same place" and the havn't been updated they could be treated as being the same.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 15-Nov-2004 10:37:59   

arschr wrote:

I understand that there are issues with this. Such when are things really the same and when are they not (with out getting into deep philosophy).

But if you provide a way to transform a set of entities and collections into a dataset (which I think would be good) you would have to deal with this. As a practical matter if items from the database have a timestamp field and multiple entities came from the "same place" and the havn't been updated they could be treated as being the same.

Indeed, which comes down to a concurrency control scheme used by the developer. After all, it's just data and the only way to distinguish one blob of data from the other is to give portions of that data a semantical meaning like 'PK' or 'ID'. Furthermore, that semantical meaning is only in context in the system where there can be only one of these, i.e.: the database system: I can replicate any entity in the system on as much systems as I want, having a lot of instances but frankly, it's the same data, semantically, and in fact mirrors of the sole entity in the database.

Uniquing is possible though, as long as the context in which uniquing takes place is known and well defined. For example an in-memory transaction. I can write a class Context which is holding a DataAccessAdapter class and a cache. It sports an Add() method for new entities and every entity fetched through the adapter is stored in the cache or retrieved from the cache in that context, and you can carry around that context to areas in your program as you please, as long as you understand that entities are only unique in the context of that Context (pun intended wink ). I've planned such a class. The disadvantages are huge though, especially performance, as multi-entity fetches take more time (every entity fetched has to be compared with an instance in the cache) but that can give oppertunities which can be helpful. What is good about having a Context is that you can simply use set-and-forget logic. I.e.: the Context knows each entity in its context, so you just commit the context and all changed entities are saved.

Frans Bouma | Lead developer LLBLGen Pro