none
Change Value in LINQ-to-SQL OnPropertyChanging Partial Method RRS feed

  • Question

  • Hi everyone.
    Im trying to modify a value in my BLL via using linq2sql's partial method which is fired when that specific property is edited by user
    specifically i want to set the "cell" field to a full canonical-formatted cell(mobile) number

    here is my code which gets fired
    Private Sub OnCellChanging(ByVal value As String)
            value = Regex.Replace(value, "\+| |\(|\)|-", "")
            value = MiniCanon(value)
        End Sub
    the problem is that the new "value" value is not persisted back to the db. the code fires alright and the local "value" variable gets the new string which i want. but it just gets lost as soon as the code exists.
    i tried putting
    Cell=minicanon(value)
    but that puts code in an endless loop
    what can be done?
    thanks
    Thursday, October 29, 2009 2:21 PM

Answers

  • Hi Yisman,


    The OnPropertyChanging partial methods aren't meant for changing the value, thats why the new value is passed by value and not by reference. This event occurs when you have decided that the value WILL change. The only thing you can do in your OnPropertyChanging() methods is that you can throw a ValidationException() (or any other appropriate exception) if you don't want the value to be changed.

    In this scenario where you want to format the given cell number, an option would be to create another property wrapper (in a partial class) in which you format and set the underlying Cell property like this:

    Public Property RawCellNumber() As String
    Get
      ' you may return the formatted Cell No. here
    End Get
    Set
      ' set the underlying Cell property after applying regex
      Me.Cell = Regex.Replace(value, "\+| |\(|\)|-", "")
    End Set
    End Property

    Hope that helps.

    Regards,

    Syed Mehroz Alam
    My Blog | My Articles
    • Proposed as answer by KristoferAEditor Tuesday, November 3, 2009 5:54 AM
    • Edited by Syed Mehroz Alam Tuesday, November 3, 2009 5:57 AM please excuse my vb, i work in c#
    • Marked as answer by Zhipeng Lee Wednesday, November 4, 2009 9:27 AM
    Tuesday, November 3, 2009 5:27 AM
  • As Syed says, better have a separate property that does the regex modifications etc. But if you really must do it in OnCellChanging, just add a class level private flag to avoid a forever recursive thing. E.g.:

    private bool _inCellChanging = false;

    Private Sub OnCellChanging(ByVal value As String)
      if (_inCellChanging == false) then
        _inCellChanging = true;
        value = Regex.Replace(value, "\+| |\(|\)|-", "")
        Cell = MiniCanon(value)
        _inCellChanging = false;
      end if
    End Sub


    Kristofer - Huagati Systems Co., Ltd.
    Cool tools for Linq-to-SQL and Entity Framework:
    huagati.com/dbmltools (add-in with new features for Visual Studio 2008's L2S and EF designers)
    huagati.com/L2SProfiler (Query profiler for Linq-to-SQL and LLBLGen Pro)
    • Marked as answer by Zhipeng Lee Wednesday, November 4, 2009 9:27 AM
    Tuesday, November 3, 2009 5:58 AM
    Answerer

All replies

  • Hi YismanOl,

    You can try to replace 'ByVal' with 'ByRef' to see if it works. In fact, you can refer to the partial methods generated by the OR designer. Compare yours with the machine-generated code and find out the difference. I hope this might help  you.




    Best regards,
    Charlie Lee

    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Monday, November 2, 2009 9:48 AM
  • Hi Zhipeng Lee
    i appreciate your posting
    i tried both suggestions
    1: putting ByRef in my partial method resulted in the following compilation error:
    Private Sub OnCellChanging(value As String)' and 'Private Sub OnCellChanging(ByRef value As String)' cannot overload each other because they differ only by parameters declared 'ByRef' or 'ByVal'.
    2: so i had a look at the partial method in the orm designer. it looks like this:
    Partial Private Sub OnCellChanging(value As String)
    End Sub
    Partial Private Sub OnCellChanged()
    End Sub
    it does not show byref or byval thought that usually means byval.
    if so, it the exact same signature like my own method
    the basic problem is that these methods are empty, so i cant know how it would assign values to properties

    please reply with some more advice
    i appreciate your help very much
    all the best




    Monday, November 2, 2009 5:27 PM
  • Hello,

    Scott Gu has a great blog series on Linq to Sql and has provided various examples on anything linq related.

    The link here: http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx

    Under the

    Custom Property Validation Support

    He provides good examples of custom property changing validation just like what you are doing but his example are in csharp (should not be a problem converting to vb.net)

    I don't know if any of this is relevant to your problem but it could help in troubleshooting your problem!

    Hope this helps!
    Monday, November 2, 2009 5:44 PM
  • Thank you d13mr3m1x

    But no, scotts examples as well as most examples on the web, only use the OnChanging method for validation. He does not change the value or set it in any way. I'm afraid the question is stil open

    I still appreciate your joining and taking the time to answer.

    Any other ideas? Anyone?

    Thank you all
    Monday, November 2, 2009 7:50 PM
  • Hi Yisman,


    The OnPropertyChanging partial methods aren't meant for changing the value, thats why the new value is passed by value and not by reference. This event occurs when you have decided that the value WILL change. The only thing you can do in your OnPropertyChanging() methods is that you can throw a ValidationException() (or any other appropriate exception) if you don't want the value to be changed.

    In this scenario where you want to format the given cell number, an option would be to create another property wrapper (in a partial class) in which you format and set the underlying Cell property like this:

    Public Property RawCellNumber() As String
    Get
      ' you may return the formatted Cell No. here
    End Get
    Set
      ' set the underlying Cell property after applying regex
      Me.Cell = Regex.Replace(value, "\+| |\(|\)|-", "")
    End Set
    End Property

    Hope that helps.

    Regards,

    Syed Mehroz Alam
    My Blog | My Articles
    • Proposed as answer by KristoferAEditor Tuesday, November 3, 2009 5:54 AM
    • Edited by Syed Mehroz Alam Tuesday, November 3, 2009 5:57 AM please excuse my vb, i work in c#
    • Marked as answer by Zhipeng Lee Wednesday, November 4, 2009 9:27 AM
    Tuesday, November 3, 2009 5:27 AM
  • As Syed says, better have a separate property that does the regex modifications etc. But if you really must do it in OnCellChanging, just add a class level private flag to avoid a forever recursive thing. E.g.:

    private bool _inCellChanging = false;

    Private Sub OnCellChanging(ByVal value As String)
      if (_inCellChanging == false) then
        _inCellChanging = true;
        value = Regex.Replace(value, "\+| |\(|\)|-", "")
        Cell = MiniCanon(value)
        _inCellChanging = false;
      end if
    End Sub


    Kristofer - Huagati Systems Co., Ltd.
    Cool tools for Linq-to-SQL and Entity Framework:
    huagati.com/dbmltools (add-in with new features for Visual Studio 2008's L2S and EF designers)
    huagati.com/L2SProfiler (Query profiler for Linq-to-SQL and LLBLGen Pro)
    • Marked as answer by Zhipeng Lee Wednesday, November 4, 2009 9:27 AM
    Tuesday, November 3, 2009 5:58 AM
    Answerer
  • thank you all for the great ideas

    either 1 requires extra coding. (this is something i might want to do on many properties) so if Syed is correct, which definetly seems so. then i would probably have to go with the OnValidate method. which might be inefficient. cause i will be modifying the cell field at any update of the row. but it seems the most maintainable solution as of now.

    even though KristoferA's solution is pretty clean as well. it does require an extra boolean and several lines PER property. but it just might work out

    I thank you all for chipping in. i marked your posts as helpful, but still open to additional ideas

    all the best

    Tuesday, November 3, 2009 7:31 AM
  • hi
    i just now got around to trying your code, but unfortunatley it does not work. here is the code im using:
    Dim IsCellChanging As Boolean
        Private Sub OnCellChanging(ByVal value As String)
            If Not IsCellChanging Then
                IsCellChanging = True
                Cell = MiniCanon(Regex.Replace(value, "\+| |\(|\)|-", ""))
                IsCellChanging = False
            End If
        End Sub
    the new value holds a bit longer then w/o your local variable. but still it gets lost somewehre thru the iterations. in the end when it is submitted to db, it is revreted to its original value, before my "canonization".

    did i translate the c# correctly? i think i did
    all the best
    Thursday, November 12, 2009 11:40 AM
  • Try using the partial method for OnCellChanged instead of OnCellChanging. OnCellChanging happens before the property value is set, so after this method returns the property setter will overwrite the canonicalized value that you create here. The only difference between the methods is that you will not get any parameters, so instead you can do this:

    Cell = MiniCanon(Regex.Replace(Cell, "\+| |\(\)|-", ""))
    Blog - http://blogs.rev-net.com/ddewinter/ Twitter - @ddewinter
    Thursday, November 12, 2009 2:32 PM
    Answerer