locked
Why does querying a related entity cause the _changed method to fire!!!??? RRS feed

  • Question

  • I have an entity Vendor that has FK properties Country and State.  I use the Country_Changed method to set the State to Nothing each time the Country is changed.

    Country_Changed()
    If (Me.Country Is Nothing) Then
    Me.State = Nothing
    ElseIf (Me.Country IsNot Nothing) Then
    Me.State = Nothing
    EndIf

    This works fine.

    Here is the problem.  I have another entity VendorContact that is a child of Vendor.  VendorContact also has FK properties Country and State.  VendorContact has a Boolean property UseVendorAddress.  I use the method UseVendorAddress_Changed (on the VendorContact entity) to set the VendorContact.Country and VendorContact.State to the value of Vendor.Country and Vendor.State.  At first I tried to do this directly on the navigation properties but this caused the Country_Changed method to fire on the Vendor entity.

    UseVendorAddress_Changed()
    If (Me.Vendor IsNot Nothing) Then
    If (Me.UseVendorAddressChanged = True) Then
    If (Me.Vendor.Country IsNot Nothing) Then
    Me.Country = Me.Vendor.Country
    EndIf
    If (Me.Vendor.State IsNot Nothing) Then
    Me.State = Me.Vendor.State
    EndIf
    EndIf
    EndIf

    It makes no sense to me why the Country_Changed method on the Vendor entity would fire (since nothing should be changing on the Vendor entity), but I suppose that because of the direct assignment via navigation property I can somewhat understand that.  It gets better...

    To work around this I tried to use linq to get the Country and assign directly from the Country entity, thus bypassing the Vendor entity and the dreaded Country_Changed method altogether, or so I thought:

    UseVendorAddress_Changed()
    If (Me.Vendor IsNot Nothing) Then
    If (Me.UseVendorAddressChanged = True) Then
    If (Me.Vendor.Country IsNot Nothing) Then
    
    Dim country = from c In Me.DataWorkspace.mydatasource.Countries
    Where (c.CountryID = Me.Vendor.Country.CountryID)
    Select c
    
    Dim result = country.Single()
    
    If (result IsNot Nothing) Then
    Me.Country = result
    EndIf
    
    EndIf
    EndIf
    EndIf

    This also fires the Country_Changed method on the Vendor entity (which sets the Vendor.State to Nothing and fires validation on the Vendor entity)!!

    Please help!  This should be easy...

    -In case your're wondering, there is no Vendor collection in the screen I am using to test/repro the above issue.  No code calls any changes whatsoever to the Vendor entity -- just querying it.



    • Edited by Hessc Tuesday, February 5, 2013 2:49 PM
    Tuesday, February 5, 2013 2:30 PM

Answers

  • Hi Hessc,

    I think you've ran into the same "Quirk" than had me going around in circles for days.

    It seems that  whenever a property in a related entity is read in code, Light Switch fires a change event on the parent, but doesn't actually change any properties on the parent.

    Garth Henderson also ran into the issue and came to my rescue suggesting to put this at the start of the _Changed methods:

    c#

     if (this.Details.EntityState == EntityState.Unchanged || this.Details.EntityState == EntityState.Deleted
                    || this.Details.EntityState == EntityState.Discarded ) return;

    vb.net

    If Me.Details.EntityState = EntityState.Unchanged OrElse Me.Details.EntityState = EntityState.Deleted OrElse Me.Details.EntityState = EntityState.Discarded Then
    	Return
    End If

    Worked a treat, and I now put this at the start of all _Changed events just in case.

    Here's links to my post and Garth's own:

    Computed property causing changes in related entities

    A Screen Property Changed EnityState = Unchanged when value is changed


    John

    • Proposed as answer by LaurentzT Wednesday, February 6, 2013 11:23 AM
    • Marked as answer by Hessc Wednesday, February 6, 2013 6:01 PM
    Wednesday, February 6, 2013 9:56 AM

All replies

  • Hi Hessc,

    I think you've ran into the same "Quirk" than had me going around in circles for days.

    It seems that  whenever a property in a related entity is read in code, Light Switch fires a change event on the parent, but doesn't actually change any properties on the parent.

    Garth Henderson also ran into the issue and came to my rescue suggesting to put this at the start of the _Changed methods:

    c#

     if (this.Details.EntityState == EntityState.Unchanged || this.Details.EntityState == EntityState.Deleted
                    || this.Details.EntityState == EntityState.Discarded ) return;

    vb.net

    If Me.Details.EntityState = EntityState.Unchanged OrElse Me.Details.EntityState = EntityState.Deleted OrElse Me.Details.EntityState = EntityState.Discarded Then
    	Return
    End If

    Worked a treat, and I now put this at the start of all _Changed events just in case.

    Here's links to my post and Garth's own:

    Computed property causing changes in related entities

    A Screen Property Changed EnityState = Unchanged when value is changed


    John

    • Proposed as answer by LaurentzT Wednesday, February 6, 2013 11:23 AM
    • Marked as answer by Hessc Wednesday, February 6, 2013 6:01 PM
    Wednesday, February 6, 2013 9:56 AM
  • Hi, Thank you so much, this solved my problem completely!  Note that after the Return you need to add "Else" before inserting your _changed code.  Just pointing it out but I think that is fairly obvious.  Anyway, you saved me a great deal of effort --  I thought I was going to have use INotifyPropertyChanged events in every screen to achieve the desired results.  Thanks again!!
    Wednesday, February 6, 2013 6:06 PM