OnPropertyChange on fetching entity and sub entities with Prefetch path

Posts   
 
    
Praveen
User
Posts: 31
Joined: 09-Jan-2012
# Posted on: 09-Jan-2012 03:33:08   

Hi,

I am doing a fetch with below code. I want to set OnProperty change to my sub entities as well. Can someone help me with this?

public T Find(IEntity2 obj, List<IPrefetchPathElement2> prefetchPathElement2) { var entityType = (EntityType)obj.LLBLGenProEntityTypeValue; using (var adapter = new DataAccessAdapter()) { adapter.FetchEntity(obj, SetPerfetchPath(entityType, prefetchPathElement2)); BindOnPropertyChange(obj);

            return (T)obj;
        }
    }

public void BindOnPropertyChange(IEntity2 iEntity2) { var obj = iEntity2 as CommonEntityBase; if (obj != null) { obj.PropertyChanged += iEntity2_PropertyChanged; } }

This is working fine with my base entity field changes. But, for sub entities fetched using prefetchpathelement onproperty change doesnt work with this.

thanks in advance..

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 09-Jan-2012 09:55:26   

You may recursively call BindOnPropertyChange() on entities returned from obj.GetDependentRelatedEntities() & obj.GetDependingRelatedEntities().

Praveen
User
Posts: 31
Joined: 09-Jan-2012
# Posted on: 09-Jan-2012 10:33:49   

Actually, this is already done in my code..

private void GetChildObjects(IEntity2 obj, List<IPrefetchPathElement2> prefetchPathElement2) { IList relatedEntities = obj.GetDependingRelatedEntities(); if (prefetchPathElement2 != null) { foreach (var relatedEntity in relatedEntities) { ((IEntity2)relatedEntity).PropertyChanged += iEntity2_PropertyChanged; } } }

My problem is when the following code is executed to get entity collection list. I am binding this to my grid and when there is a property level change, I want to fire onproperty change from UI.

public IList FindAll(IEntity2 obj, IRelationPredicateBucket filter, List<IPrefetchPathElement2> prefetchPathElement2) { var entityType = (EntityType)obj.LLBLGenProEntityTypeValue; using (var adapter = new DataAccessAdapter()) { var entityCollection = new EntityCollection(obj.GetEntityFactory()); adapter.FetchEntityCollection(entityCollection, filter, SetPerfetchPath(entityType, prefetchPathElement2)); BindOnPropertyChange(obj); GetChildObjects(obj, prefetchPathElement2); return entityCollection.GetList(); } }

Is there a way to bind each row of the collection to onproperty change event?

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 09-Jan-2012 12:04:15   

My problem is when the following code is executed to get entity collection list. I am binding this to my grid and when there is a property level change, I want to fire onproperty change from UI.

public IList FindAll(IEntity2 obj, IRelationPredicateBucket filter, List<IPrefetchPathElement2> prefetchPathElement2) { var entityType = (EntityType)obj.LLBLGenProEntityTypeValue; using (var adapter = new DataAccessAdapter()) { var entityCollection = new EntityCollection(obj.GetEntityFactory()); adapter.FetchEntityCollection(entityCollection, filter, SetPerfetchPath(entityType, prefetchPathElement2)); BindOnPropertyChange(obj); GetChildObjects(obj, prefetchPathElement2); return entityCollection.GetList(); } }

Is there a way to bind each row of the collection to onproperty change event?

So iEntity2_PropertyChanged won't get called on related entities?!

I'm not sure what do you mean by your last question, so if you please could give an example, how are you doing databinding, which fields are you using (from related entities I suppose)

And in the mean time, please check this thread, which seems discussing a similar case. http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=11104

Praveen
User
Posts: 31
Joined: 09-Jan-2012
# Posted on: 09-Jan-2012 14:41:19   

I have two functions.

  1. to fetch the entity and its List<IPrefetchPathElement2>
  2. to fetch the entity collection and its List<IPrefetchPathElement2>

Code for bullent point 1: public T Find(IEntity2 obj, List<IPrefetchPathElement2> prefetchPathElement2) { var entityType = (EntityType)obj.LLBLGenProEntityTypeValue; using (var adapter = new DataAccessAdapter()) { adapter.FetchEntity(obj, SetPerfetchPath(entityType, prefetchPathElement2)); BindOnPropertyChange(obj); GetChildObjects(obj, prefetchPathElement2); return (T)obj; } }

Code for bullet point 2: public IList FindAll(IEntity2 obj, IRelationPredicateBucket filter, List<IPrefetchPathElement2> prefetchPathElement2) { var entityType = (EntityType)obj.LLBLGenProEntityTypeValue; using (var adapter = new DataAccessAdapter()) { var entityCollection = new EntityCollection(obj.GetEntityFactory()); adapter.FetchEntityCollection(entityCollection, filter, SetPerfetchPath(entityType, prefetchPathElement2)); BindOnPropertyChange(obj); GetChildObjects(obj, prefetchPathElement2); return entityCollection.GetList(); } }

public void BindOnPropertyChange(IEntity2 iEntity2) { var obj = iEntity2 as CommonEntityBase; if (obj != null) { obj.PropertyChanged += iEntity2_PropertyChanged; } }

    void iEntity2_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        Save(sender as CommonEntityBase);
    }

Please provide me sample code to attach PropertyChanged event to the List<IPrefetchPathElement2> list.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 09-Jan-2012 16:35:58   

It seems that you are not reading my replies.

First I've asked ytou a questionand you did not reply to it, and I've asked you to check a link, and you have not replied to whether it helped you or not.

Then you throw some code and asks us to help you out.

So please reply to our questions and help us understand your issue, so we can better help you.

Praveen
User
Posts: 31
Joined: 09-Jan-2012
# Posted on: 09-Jan-2012 16:49:14   

Sorry that I didnt answer couple of your questions...

So iEntity2_PropertyChanged won't get called on related entities? my answer is no

I also had a look at the link you gave, but, it also didnt help much...

I have shared two methods in my previous post. In those methods, I am not passing any relation entity predicate, rather just passing List<IPrefetchPathElement2>. I may be missing something simple in my method, please help me to identify it..

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 10-Jan-2012 05:48:26   

Ok. Some points:

  1. The GetChildObjects as you have it above won't work if you pass an EntityCollection.
  2. The IPrefetchPathElement is just useful when you design the PrefetchPath, it's no longer useful when you already fetch the entities. You have to inspect the already fetched elements regardless of the path.

To get things easier, there is an util class in LLBLGen runtime called ObjectGraphUtils, it has a method which returns a flat list of the graph, you can use that list to bind the event handler. It would work for the root entity, its m:1 related entities and its 1:n ones. I cooked the methods for you:

private void BindEvents(IEntity2 obj)
{
    ObjectGraphUtils ogu = new ObjectGraphUtils();
    List<IEntity2> flatList = ogu.ProduceTopologyOrderedList(obj);
            
    foreach (var entity in flatList)
    {
        entity.PropertyChanged += iEntity2_PropertyChanged;
    }           
}

private void BindEvents(IEntityCollection2 coll)
{
    foreach (IEntity2 entity in coll)
    {
        BindEvents(entity);
    }
}

so, your code should look like:

public T Find(IEntity2 obj, List<IPrefetchPathElement2> prefetchPathElement2)
        {
            var entityType = (EntityType)obj.LLBLGenProEntityTypeValue;
            using (var adapter = new DataAccessAdapter())
            {
                adapter.FetchEntity(obj, SetPerfetchPath(entityType, prefetchPathElement2));
                BindEvents(obj);
                return (T)obj;
            }
        }

public IList FindAll(IEntity2 obj, IRelationPredicateBucket filter, List<IPrefetchPathElement2> prefetchPathElement2)
        {
            var entityType = (EntityType)obj.LLBLGenProEntityTypeValue;
            using (var adapter = new DataAccessAdapter())
            {
                var entityCollection = new EntityCollection(obj.GetEntityFactory());
                adapter.FetchEntityCollection(entityCollection, filter, SetPerfetchPath(entityType, prefetchPathElement2));
                BindEvents(entityCollection);
                return entityCollection.GetList();
            }
        }

void iEntity2_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
     Save(sender as CommonEntityBase);
}

David Elizondo | LLBLGen Support Team
Praveen
User
Posts: 31
Joined: 09-Jan-2012
# Posted on: 18-Jan-2012 10:45:42   

Thanks.. that helped me to fix the issue.