wpfvb.netentity-frameworkself-tracking-entities

I cant add an item to a Self Tracking Entity Collection with Navigation Properties


I have a WPF 4 application where my data is accessed through Self Tracking Entities(STE 5). I have a WPF content control with its data-context set to a model class (vendor) of the STE. The vendor class has a navigation property of vendor_accounts. I can successfully get a collection of these vendor accounts and bind them to a listview within the content control. However, when I try to add a new vendor_account object to to the collection I get the following error

Cannot change ObservableCollection during a CollectionChanged event.

Here is the simplified vb.NET code that I use to add to the collection of the listview:

Private Sub AddAccountExecute()

    Dim newAcc As New vendor_account With {.chrAccName = "New Account Name", .chrAccNumber = "New #"}

    VendorSelection.vendor_account.Add(newAcc)
    ''FTC_Context is the object context for the STE data access model
    FTC_Context.SaveChanges()

End Sub

This error is thrown in the following sub which is in the generated template code for the STE. The error appears on the line previousValue.vendor_account.Remove(Me):

Private Sub Fixupvendor(ByVal previousValue As vendor)
    If IsDeserializing Then
        Return
    End If

    If previousValue IsNot Nothing AndAlso previousValue.vendor_account.Contains(Me) Then
        previousValue.vendor_account.Remove(Me)
    End If

    If vendor IsNot Nothing Then
        vendor.vendor_account.Add(Me)

        idVendor = vendor.idVendor
    End If
    If ChangeTracker.ChangeTrackingEnabled Then
        If ChangeTracker.OriginalValues.ContainsKey("vendor") AndAlso
            ChangeTracker.OriginalValues("vendor") Is vendor Then
            ChangeTracker.OriginalValues.Remove("vendor")
        Else
            ChangeTracker.RecordOriginalValue("vendor", previousValue)
        End If
        If vendor IsNot Nothing AndAlso Not vendor.ChangeTracker.ChangeTrackingEnabled Then
            vendor.StartTracking()
        End If
    End If
End Sub

I commented out that line and the items can be successfully added to the account_vendor collection (this is not an acceptable fix because it modifies the automatically generated code which gets recreated everytime i update my STE model).
So I added back in the FTC_Contect.SaveChanges() with the above line of code commented out to test if the database gets updated. But now I get the following error on save changes line:

Multiplicity constraint violated. The role 'vendor' of the relationship 'FTC_devModel.FK_vendor_account_vendor' has multiplicity 1 or 0..1.

I am new to STE and am having trouble with it.

So, my question is, can someone help me by providing an example of how to add / delete records with "navigation properties" or help me correct my code above.

Thanks in advance


Solution

  • So I have a working "solution" now. Maybe hack is a better term.

    I changed the STE entity framework template (FTCModel.tt) to exclude the line: previousValue.vendor_account.Remove(Me)

    and I changed the addAccountExecute sub code to:

    Dim vendorAccount As New vendor_account With {.idVendor = idVendor,
                                                                  .chrAccName = "New Account Name",
                                                                  .chrAccNumber = "New #"}
    FTC_Context.vendor_account.AddObject(vendorAccount)
    FTC_Context.SaveChanges()
    

    which uses the STE context to add the object and not the vendor object like in the first code I provided.

    So it is working, but this feels like a hack, like I am doing something wrong still. The fixup method is called from the "vendor" setter property of the vendor_account class and it attempts to remove and then add the vendor_account object to the vendor, which then throws the error I outlined in my first post.

    I still don't understand why I got the error in the first place. Maybe it has something to do with the WPF binding a listview directly to the navigation property (of type trackablecollection(of T)).

    For now I will use this but I would really appreciate if someone could help me understand this problem a little better.