Refetch data structure

Posts   
 
    
Miksovic avatar
Miksovic
User
Posts: 6
Joined: 16-Apr-2008
# Posted on: 15-May-2008 17:36:38   

Hi,

I am using a classic model/view/controller scenario. The model contains LLGenEntity, keeps the structure of fetched entities and takes care of data persistance. The view's datasource binds on an arbitrary part of model's structure. Problem is when I refetch the data (refresh command on controller), model performs fetch and all collections that were binded to View's datasource loose their reference.

Is there any way to fetch existing structure, that keeps all collection instances in the structure the same and just fill them with updated (refreshed) entities from the database?

arschr
User
Posts: 894
Joined: 14-Dec-2003
# Posted on: 15-May-2008 21:22:51   

I'm not sure I completely understand your requirements, but ... Have you looked at the Context object?

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 16-May-2008 10:02:52   

Maybe if you'd post some code snippets the case would be much clearer.

Anyway I too, think that maybe you need to use the Context. Please check the manual's section "Using the generated code -> SelfServicing/Adaptere -> Using the context"

Miksovic avatar
Miksovic
User
Posts: 6
Joined: 16-Apr-2008
# Posted on: 17-May-2008 01:55:00   

Thanks a lot. That solved the problem. (I didn't notice the Context chapter :-). But another problem occures. When user deletes some entities on client, refreshing the data on another client don't affect that (changing/adding data works well). Is there any way to identify deleted rows (in database) in whole structure after refetching? It means when the same entity (as before) is fetched but some data are deleted (in the mean time) from database, is there any way to remove deleted entities from fetched structure?

Thanks for answer

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 17-May-2008 05:03:16   

That's by design. This is copied from the maual (LLBLGenPro help -> Using the generated code -> (Adapter | SS) -> using the context - Remarks):

Deleted entities which are deleted in the database directly are not picked up by the Context. This is something the developer has to take into account when deleting entities directly.

So you would need to remove deleted entities manually from the context.

David Elizondo | LLBLGen Support Team
Miksovic avatar
Miksovic
User
Posts: 6
Joined: 16-Apr-2008
# Posted on: 19-May-2008 21:41:07   

Ok,

so when I want to identify deleted entities (from database) I must make fetch to another structure and then use O(N^2) algorithm to compare theese structures (new one with old one keeping context) to see which entities were deleted and then delete them from structure keeping context?

or is there any other way?

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 20-May-2008 11:37:47   

Why don't you just refetch the entire structure?

Miksovic avatar
Miksovic
User
Posts: 6
Joined: 16-Apr-2008
# Posted on: 20-May-2008 14:00:21   

If I refetch the entire structure using contex - deleted rows from database are not deleted from structure.

If I fetch the entire structure to another structure - I loose the instances of collections that are binded to GUI.

goose avatar
goose
User
Posts: 392
Joined: 06-Aug-2007
# Posted on: 20-May-2008 19:05:42   

so when I want to identify deleted entities (from database) I must make fetch to another structure and then use O(N^2) algorithm to compare theese structures (new one with old one keeping context) to see which entities were deleted and then delete them from structure keeping context?

or is there any other way?

you can always rebind the whole structure.

Miksovic avatar
Miksovic
User
Posts: 6
Joined: 16-Apr-2008
# Posted on: 20-May-2008 19:31:49   

No I can't :-). I need the same structure just without the deleted entities. I have done it yet using brute force. I just wanted to know if there is some other (easier) solution.

Thanks for answers.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39873
Joined: 17-Aug-2003
# Posted on: 21-May-2008 10:19:15   

The problem is that you have a graph (directed graph) of objects, referencing eachother. What you want is remove a couple of these objects from the graph. It's not hard to create a list of entities in the graph, you can use the ObjectGraphUtils class for that for example. The thing is that you have to reset the references in OTHER objects to the objects you want to remove otherwise the entities won't be removed from the graph.

I think you can use a trick. If I have an order instance myOrder and a customer instance myCustomer, this is true: myOrder.Customer = myCustomer; after this, this line returns true myCustomer.Orders.Contains(myOrder);

and vice versa: myCustomer.Orders.Add(myOrder); -> this is true myOrder.Customer==myCustomer;

Now, let's say myOrder is the entity you want to remove and you have a reference to it. This means that it should be removed from myCustomer.Orders. But you only have a reference to myOrder. Now, you can do: myOrder.Customer = null; this will remove myOrder from myCustomer.Orders.

But, this is of course not really scalable among an unknown set of entities. What you can do is calling GetRelatedData() on all entities you want to remove. This gives you a dictionary back with as key the name of the property (field) mapped onto the relation and as value the related entity or the collection of related entities. I'll now assume you haven't hidden any relations from one side.

What you'll now do is this:

// for adapter. For selfservicing, replace IEntity2 with IEntity
foreach(IEntity2 entity in entitiesToDelete)
{
    Dictionary<string, object> relatedData = entity.GetRelatedData();
    foreach(KeyValuePair<string, object> pair in relatedData)
    {
        IEntity2 relatedEntity = pair.Value as IEntity2;
        if(relatedEntity==null)
        {
            // not an entity or null
            continue;
        }
        relatedEntity.UnsetRelatedEntity(entity, pair.Key);
        entity.UnsetRelatedEntity(relatedEntity, pair.Key); // not necessary for 1:n/m:1 relations
    }
}

Not tested, but it should work. The last line has a comment for 1:n/m:1 relations. The call is redundant for these relations, as the first call already unsets the reference. You can avoid that call by calling entity.GetAllRelations() and traverse the relations, checking the mappedfieldname if it matches pair.Key, and then check the relation type.

Frans Bouma | Lead developer LLBLGen Pro