OnPropertyChanged() never gets called on base entity

Posts   
 
    
Sam avatar
Sam
User
Posts: 95
Joined: 30-Jun-2004
# Posted on: 05-Jan-2006 18:04:32   

For some reason my events for OnPropertyChanged are not getting fired. I have set breakpoints at various OnPropertyChanged Method which is not getting called. I have also set a breakpoint at SetNewFieldValue() which is not getting called either (the changes are persisting to the database properly). It seems like this question was answered before but I cannot find the post. Ideas?

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 06-Jan-2006 06:47:55   

A silly -but a must to ask- question? are you on debug or release mode?

OnPropertyChanged() never gets called on base entity

Another question, what do you mean by base entity?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39930
Joined: 17-Aug-2003
# Posted on: 06-Jan-2006 09:46:12   

To elaborate: SetNewFieldValue ALWAYS gets called from a property setter, so if it's not called, the field won't get a new value but because it apparently does, something else is wrong...

Frans Bouma | Lead developer LLBLGen Pro
Sam avatar
Sam
User
Posts: 95
Joined: 30-Jun-2004
# Posted on: 06-Jan-2006 16:26:36   

I am really confused about this too. Basically I have a base entity SalesEntityBaseEntity then I have SuspectEntity, ProspectEntity that derives from SalesEntityBase. The object in question has been instatiated as a ProspectEntity. Now if I set a breakpoint on the SetNewFieldValue for the ProspectEntity I will hit the breakpoint. Then when I "Go To Defenition" on base.SetNewFieldValue on the first line in the SetNewFieldValue method


bool toReturn = base.SetNewFieldValue (fieldIndex, value, checkForRefetch, false);

I am taken to the VS created meta data for the EntityBase SetNewFieldValue method. This means that even though the ProspectEntity inherits from SalesEntityBaseEntity (class decliration = public partial class ProspectEntityBase : SalesEntityBaseEntity, ISerializable) base.SetNewFieldValue is calling EntityBase.SetNewFieldValue instead of SalesEntityBaseEntity.SetNewFieldValue and that is why the OnPropertyChanged() method is not getting fired on the SalesEntityBaseEntity. I am really confused confused !

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39930
Joined: 17-Aug-2003
# Posted on: 09-Jan-2006 11:16:02   

Bug.

It should call the base method, not the entitybase method. I think the reason I did this was the problem with overriden properties: if a property is overriden in a subtype, the supertype shouldn't fire the event if the call originates from that subtype, but SHOULD fire the event if the call originates from the subtype.

Though I think what should be done is that each SetNewFieldValue() routine should simply call the entitybase version and then have a check for every field, not for only its own fields. This way the events are fired on the level it should and no duplicate events are fired.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 65
Joined: 07-Dec-2005
# Posted on: 09-Jan-2006 12:10:29   

Unless you do something different in sub entity types, the overload of SetNewFieldValue that the overriden version in an entity calls is not virtual (as you may remember from our previous epic discussion!), so it would have to call the EntityBase version, since that is the only version.

Then again, if you DO do something different for inherited entities, just ignore what I just said! simple_smile

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39930
Joined: 17-Aug-2003
# Posted on: 09-Jan-2006 13:05:25   

It's not a small problem...

AdamRobinson wrote:

Unless you do something different in sub entity types, the overload of SetNewFieldValue that the overriden version in an entity calls is not virtual (as you may remember from our previous epic discussion!), so it would have to call the EntityBase version, since that is the only version.

Then again, if you DO do something different for inherited entities, just ignore what I just said! simple_smile

I don't do anything different in de inherited entities. Let me explain what's happening simple_smile

hierarchy: entitybase employee manager

say employee calls base.SetNewFieldValue(3). SetNewFieldValue(3) is the virtual method which simply calls SetNewFieldValue(4) which does the actual work.

Ok, now manager also simply calls base.SetNewFieldValue(3). This happens to be employee.SetNewFieldValue(3). In the generated versions, these methods fire change events and make sure related references are reset if an fk is changed.

this works, UNTIL manager overrides a field of employee. In that situation, like with 'id', the change event will be fired twice: once from employee.SetNewFieldValue() and once from manager.SetNewFieldValue().

Though if you set the value through an instance of employee, you DO want the event. If you set the value through an instance of manager, you don't want the employee.SetNewFieldValue instance to do anything for that field.

That's why a derived SetNewFieldValue doesn't call it's base method. Though, this gives another problem, as shown in this thread: if a field in employee is set through a manager instance, the OnFieldChanged event isn't fired. What's worse: if the field is an FK, the reference of the related entity through that fk isn't reset. Well, it's a feature so it should work. It's not a big drama if it doesn't but if you rely on it, because it's a feature, you're in trouble, hence 'it's a problem' simple_smile

The main issue with this is that the worker method is in the runtime lib, and the calling methods are in the templates. This means that a fix in the templates AND the runtimes requires customers to update both, which is not what should be done, as it requires a public api change on the runtimes and we avoid that at all costs IF it affects the templates, which such a fix does. I've to see how to solve this without major restructuring of this drama-method.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39930
Joined: 17-Aug-2003
# Posted on: 09-Jan-2006 13:45:21   

Ok, looking at it more closely, I think it's very easy to solve, as the problematic element of it: overriden fields, are always on different field indexes. So if I have employee.id and manager.id, the fieldindex of manager.id isn't in employee's field index enum, so employee won't fire the event twice, simply because it will ignore the field index for the change events and will simply return. I'm currently writing some code which actually calls in the way I described in my previous posting, plus an enum overflow check to see if it works.

(edit). If I call the non-virtual SetNewFieldValue() only from the root entity of a hierarchy, (for a normal entity nothing changes) would that break your code, Adam? I'm pretty sure it won't but just in case.

(edit2): I've a fix for this ready. I've to push it through the buildtests for all template set setups but I'm pretty confident it will hold. Sam, please notify me if / when you want to test the fix out in your setup. Adam, if you want me to send you the updated templates, let me know.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 65
Joined: 07-Dec-2005
# Posted on: 10-Jan-2006 00:32:32   

I don't see it breaking any of my stuff, but thanks for asking!

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39930
Joined: 17-Aug-2003
# Posted on: 14-Jan-2006 14:44:27   

Just a fyi: the fix is released and available in the latest templates update of jan 12th.

Frans Bouma | Lead developer LLBLGen Pro