The EntitySpaces Community

Share and learn about the EntitySpaces Architecture.
Welcome to The EntitySpaces Community Sign in | Join | Help
in
Home Forums Photos

SetColumn Woes

Last post 03-04-2008, 10:25 AM by David.Parsons. 6 replies.
Sort Posts: Previous Next
  •  03-03-2008, 12:53 PM 8244

    SetColumn Woes

    I'm trying to use and virtual column in one of my Entities.  The issue I'm experiencing is that whenever the virtual field (CustomerNote) is updated on my form, the Set gets called as it should (with appropriate value) but the SetColumn call fails (with no error message).  The virtual column's value is never set to the new value.  Am I doing something incorrectly?  Is what I'm trying to do even supported?  The initial GetColumn call works perfectly fine by the way.  I realize I could probably remove the column from the GetProspect call and replace it in the Property Get/Set, but I'd prefer to grab it from the database in once call vs. two.

    Here's the code:

     

    Code:
    1    'In my Custom Entity:        
    2    
    3    	Protected Overloads Overrides Function GetLocalBindingProperties() As List(Of EntitySpaces.Core.esPropertyDescriptor)
    4                Dim props As New List(Of EntitySpaces.Core.esPropertyDescriptor)
    5    
    6                props.Add(New EntitySpaces.Core.esPropertyDescriptor(Me, "CustomerNote", GetType(String)))
    7    
    8                Return props
    9            End Function
    10   
    11   	Public Property CustomerNote() As String
    12               Get
    13                   Return Me.GetColumn("CustomerNote").ToString
    14               End Get
    15               Set(ByVal value As String)
    16                   Me.SetColumn("CustomerNote", value)
    17               End Set
    18           End Property
    

     Code:

    1    'My Data Access code to fill a Prospect Entity
    2    
    3        Public Function GetProspect(ByVal ProspectID As Integer) As BusinessObjects.Prospect Implements IDataAccess.GetProspect
    4            Dim p As New BusinessObjects.ProspectQuery("p")
    5            Dim c As New BusinessObjects.CustomerQuery("c")
    6    
    7            p.Select(p)
    8            p.Select(c.Note.As("CustomerNote"))
    9            p.InnerJoin(c).On(p.CustomerID = c.CustomerID)
    10           p.Where(p.ProspectID.Equal(ProspectID))
    11   
    12           Dim Prospect As New BusinessObjects.Prospect
    13           Prospect.Load(p)
    14   
    15           Return Prospect
    16       End Function
    


     
     

  •  03-03-2008, 2:29 PM 8247 in reply to 8244

    Re: SetColumn Woes

    Why do you think SetColumn is failing? Remember, Virtual Columns are for binding purposes. When you call prospect.Save, no Virtual Columns get stored in the database. Somewhere in your Form's save routine, you will need to set customer.Note = prospect.CustomerNote, and save both tables. Perhaps you can use a hierarchical property, if one exists, and Customer is not an "UpTo"?
    David Neal Parsons
    www.entityspaces.net
  •  03-03-2008, 4:02 PM 8249 in reply to 8247

    Re: SetColumn Woes

    Totally understand that I need to handle the Save separately.  I didn't include that section of code because immediately after the "Set" (line 16 of the 1st code snippet), I check the value of CustomerNote and it's the original value that was read in from the call to GetProspect.  I am sure I'm doing something incorrect somewhere along the lines because the "value" parameter being passed in to the Set is correct.  It's just that checking it immediately afterwards, the value isn't.  Did that make sense?

     

  •  03-03-2008, 4:47 PM 8250 in reply to 8249

    Re: SetColumn Woes

    I think I know what this is related to. Try the same code but without give "Note" an alias and see if it works (using "Note" obviously) you can look the Table.Column property after the load to see what the column is truly named by the way.

    EntitySpaces | Twitter | BLOG
  •  03-03-2008, 6:14 PM 8251 in reply to 8250

    Re: SetColumn Woes

    OK, I've made some progress with that change.  I guess my property name having the same name as the aliased field was a no-no.  I'll make sure I don't do that again.

    I'm still having an issue that I'm reasonably sure you wouldn't believe me if I told you.  I'm gonna attempt to create a sample project reproducing the issue.  Of course the reliance on 3rd party UI controls (DevExpress) mucks up doing that easily, but I'll try to do it without them.

    At the risk of embarrassing myself, I'll tell you real quick what the issue is.  In the click event of my Save button, I'm calling a function called what-other-than "Save".  While I'm in the click handler (btnSave_Click), my CustomerNote property returns the proper (i.e. new) value.  I have a breakpoint set on the Save function (literally on the Private Function Save line) and when I hit that line, CustomerNote shows the old value.  I obviously have a breakpoint in the Set of CustomerNote and it's absolutely not being called again.  I honestly have no clue what could be causing this seemingly bizarre behavior.  The only thing I could think of is there's some weird binding issue going on.  The Prospect object is bound to a BindingSource and the CustomerNote field is set up properly in the IDE.

     

    Code:
    1        Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
    2 SaveResult = Save()
    3 4 Select Case SaveResult
    5 Case Enums.EditResultType.Failed
    6 Exit Sub
    7 8 Case Else
    9 If
    SaveResult <> Enums.EditResultType.NoChanges Then
    10 If
    CallingForm.Name = "ProspectList" Then CType(CallingForm, ProspectList).FillData()
    11 End If
    12 End Select
    13 14 Me
    .Close()
    15 End Sub

     
    Code:
    1        Private Function Save() As Enums.EditResultType
    2 'TODO: lookup newly added customer name and see if there's a match 3 Dim SomethingChanged As Boolean = IsDirty
    4 5 Try 6 DataAccessFactory.GetDataAccess.SaveProspect(Prospect, Appt)
    7 8 Catch ex As Exception
    9 HandleError(ex, True)
    10 Return Enums.EditResultType.Failed
    11 12 End Try
    13 14 If Not
    SomethingChanged Then
    15 Return
    Enums.EditResultType.NoChanges
    16 Else
    17 Return
    Enums.EditResultType.Saved
    18 End If
    19 End Function

     


     

  •  03-03-2008, 7:50 PM 8252 in reply to 8251

    Re: SetColumn Woes

    The saga continues.  I was unsuccessful created a test project because I'm receiving an obscure error while performing the join (Value cannot be null. Parameter name: key in GetProviderMetadata).  I have to assume I'm just blind at this point because I don't see what's causing that.

    That being said, I tried 2 other things in my real project.  First I tried to use the .Query.es.QuerySource trick to use a view to load my object.  I was 99.9% certain the results would be the same as constructing the query using the dynamic API.  I was correct.

    Next I tried to just do away with the "data-bound" virtual column and just use a private variable within the my custom Prospect object.

    I replaced:

     

    Code:
    1            'Public Property CustomerNote() As String
    2            '    Get
    3            '        Return Me.GetColumn("Note").ToString
    4            '    End Get
    5            '    Set(ByVal value As String)
    6            '        Me.SetColumn("Note", value)
    7            '    End Set
    8            'End Property
    9    
    10           Public Property CustomerNote() As String
    11               Get
    12                   If _CustomerNote = Nothing Then
    13                       Dim c As New BusinessObjects.Customer
    14                       c.LoadByPrimaryKey(Me.CustomerID.Value)
    15                       _CustomerNote = c.Note
    16                   End If
    17   
    18                   Return _CustomerNote
    19               End Get
    20               Set(ByVal value As String)
    21                   _CustomerNote = value
    22               End Set
    23           End Property
    

    This works perfectly well.  I should be happy that I have things functioning properly but I'd really like to understand if my original gameplan is a viable one since it makes a whole lot more sense to me.  The major negative to this particular approach is that I'll be making an extra  round-trip to the database unnecessarily (assuming the .GetColumn/.SetColumn method would work of course).

    Maybe if I'm less blind tomorrow, I'll be able to troubleshoot the mapName being Null error in my sample project and be able to make more sense of it at that point.  If you have any suggestions, I'm all ears.  Thanks.
     

  •  03-04-2008, 10:25 AM 8261 in reply to 8252

    Re: SetColumn Woes

    The mapName issue sounds like a config error. Unless you are using Multi-provider mode and MetadataMaps, then check that the mapName is "esDefault":

    providerMetadataKey="esDefault"

    As to binding, I was able to duplicate the issue using our test db, a DataGridView (no 3rd party control), and an entity bound to a BindingSource. Unfortunately, the behavior is so bizarre, I do not have a better work-around for you than the one you've already come up with.

    First, I took the custom entity code from your original post (8244), and put it in my custom CustomerGroup entity class.

    I added this variable to my Form1 class:

    Code:
    Dim custGroup As New CustomerGroup()

    Here is my Form1_Load:

    Code:
    Dim cgq As New CustomerGroupQuery("cg")
    Dim gq As New GroupQuery("g")
    
    cgq.Select(cgq)
    cgq.Select(gq.Notes.As("CustomerNote"))
    cgq.InnerJoin(gq).On(cgq.GroupID = gq.Id)
    cgq.Where(cgq.GroupID.Equal("10001"))
    
    custGroup.Load(cgq)
    
    BindingSource1.DataSource = custGroup
    DataGridView1.DataSource = BindingSource1

    I kept ButtonSave_Click very simple:

    Code:
    DataGridView1.EndEdit()
    BindingSource1.EndEdit()
    Console.WriteLine(custGroup.CustomerNote)

    Strange behavior #1: As you pointed out, when the form loads, the CustomerNote contains "Some notes" from the database. When I change it to "Note one", and click the Save button it reverts back to the old value. Stepping through SetColumn in the Property, I see the Row value change, but the instant I step out of the settor, it reverts back to its old value.

    Strange behavior #2: My Save does not have a Me.Close(), so I typed "Note two", clicked the Save button, and this time it stuck. All subsequent changes were retained. When I closed the Form and re-opened it, the first change got lost, but all the rest were OK.

    Strange behavior #3: If I change the object to a collection:

    Dim custGroup As New CustomerGroupcollection()

    and this line in the Save:

    Console.WriteLine(custGroup(0).CustomerNote)

    and leave everything else the same. Then the change works the first time, and every time thereafter, no problems.

    I tried some variations, eliminating the BindingSource, calling custGroup.EndEdit(), etc. Nothing helped. I was also able to duplicate this in our C# test app, so it is not a C# vs. VB thing. All I can say at this point is that we are still working on it.


    David Neal Parsons
    www.entityspaces.net
View as RSS news feed in XML