Change notification with Orcas data model

Posted Mon, Jul 9 2007 15:19 by bill

Jim Wooley recently brought my attention to some "peculiar" code in the LINQ to SQL generated properties.  It rang alarm bells with me for a different reason.. that is the runtime behavior for LINQ to SQL classes will be different in VB than it is in C#.

The code in question is in the property sets:

<Column(Storage:="_ContactName", DbType:="NVarChar(30)")> _
Public Property ContactName() As String
    Get
        Return Me._ContactName
    End Get
    Set(ByVal value As String)
        If ((Me._ContactName = Value) _
          = False) Then
            Me.OnContactNameChanging(Value)
            Me.SendPropertyChanging()
            Me._ContactName = Value
            Me.SendPropertyChanged("ContactName")
            Me.OnContactNameChanged()
        End If
    End Set
End Property


The If ((Me._ContactName = Value)  = False) Then  part is a little strange to say the least.  

What they probably wanted was If Me._ContactName <> Value Then
The C# code is if ((this._ContactName != value))

But that is not the problem. VB treats equality of strings slightly different than C#.  In VB if you use = or <>, null references are treated as being equal to String.Empty. That is If Nothing = "" Then is True.

So the question is what difference will this difference make ?  Well if you are using Nothing to represent dbNull when saving the data, (assuming the field is nullable), then the result is the field is set.  Implications of that include a plethora of concurrency issues.
Of course, data binding and standard text box controls have never been good in this regard anyway.  But it would be preferable if both C# and Vb behaved the same.  In this case using String.Equals would address that :

  If String.Equals(Me._ContactName, Value) Then

 

The ADO.NET Entity model on the other hand at present doesn't even do a check of the existing value. Here's the same code for the ContactName property set, this time using ADO.NET Entity.

Set
      Me.ReportPropertyChanging("ContactName")
      Me._ContactName = System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true, 30)
      Me.ReportPropertyChanged("ContactName")
End Set

So with the Entity model you need to check that yourself and watch for a lot of superfluous change notifications when really no change has occurred.  I presume they'll change that otherwise it would result in a lot of un-necessary writes to the database, as well as be a real pain to use in any event driven designs.

Filed under: , ,