locked
Row not found or changed - LinqDataSource

    Question

  • This appears to be a very annoying bug with LinqDataSource in Orcas Beta 2.

    Using ASP.NET data controls, some entity classes refuse to be updated.

    This isn't a concurrency thing. It's a simple database table in a development environment. There's no timestamp column. Everything's configured correctly. It only happens with one of the tables (the largest) in my app; the rest work fine.

    There's no problem updating objects programmatically with LINQ-to-SQL. I think it's a bug in the LinqDataSource.

    I've looked at

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2015324&SiteID=1
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2138980&SiteID=1

    Could we get a confirmation from Microsoft on this one?

    Thanks,
    Pete.
    Monday, September 17, 2007 2:02 PM

Answers

  • This might be caused by concurrency checks on data that is round-tripped to the client in hidden fields and then reconstituted on the server to be used as 'original' values during the update.  Some data types may loose precision when converted to text and back.  You can avoid this problem by turning on concurrency checks for this field in the mapping (a propety of the field/column in the designer.)

     

     

     

    Monday, September 17, 2007 4:47 PM

All replies

  • This might be caused by concurrency checks on data that is round-tripped to the client in hidden fields and then reconstituted on the server to be used as 'original' values during the update.  Some data types may loose precision when converted to text and back.  You can avoid this problem by turning on concurrency checks for this field in the mapping (a propety of the field/column in the designer.)

     

     

     

    Monday, September 17, 2007 4:47 PM
  • Add an event handler for the Updating event so that you can inspect the data objects before Update to see what columns are missing.  Since the data object is reconstructed on the postback, you will need to make sure that the required original values are roundtripped.

     

    Note that the databound control will roundtrip the DataKeyNames columns and any visible columns.  By default the LinqDataSource roundtrips any primary keys or columns required for optimistic concurrency, which can be disabled through the StoreOriginalValuesInViewState flag.

    Wednesday, September 19, 2007 6:42 PM
  • I just encountered the same issue -- also no timestamp field.

     

    I have a feeling it might have something to do with a null<>string.empty conversion within the LinqDataSource control/viewstate.  In my case, the original row had a null value in a nullable column.  While handling the OnUpdating event to debug, it looked like it may have been stored as an empty string in the original object.

     

    I was able to work around the exception by giving that column a default of string.empty rather than null -- but this is obviously not ideal in production when there are other dependencies on the data.
    Monday, November 12, 2007 11:14 PM
  • The databound controls will extract the values for Update, Insert and Delete from its child controls using 2-way databinding.  By default an empty textbox or label will be evaluated as an empty string, not null.  In order to treat these values as null, you'll need to use the ConvertEmptyStringToNull property on either a datasource parameter or a bound field (if using GridView or DetailsView).

     

    For instance:

    <LinqDataSource ...>

        <UpdateParameters>

            <asp: Parameter Name="MyColumn" ConvertEmptyStringToNull="true" />

        </UpdateParameters>

    </LinqDataSource>

    Tuesday, November 13, 2007 12:59 AM
  • chenriks,

     

    I am using a FormView to edit a row that already exists with a null value in one column.  I suspect that when asp.net generates the original object from LINQ (that will later be compared against the new object from the asp.net form), it might be turning SQL's null value into an empty string.

     

    I tried adding an UpdateParameter as you suggested, but it didn't seem to resolve this issue.  I suspect the UpdateParameter only applies to the new object created from the asp.net form -- not the original object created from the database perhaps?

     

    Tuesday, November 13, 2007 1:57 AM
  • The 'row not found or changed' exception happens when either the primary key isn't set, or when the old values for any columns marked for UpdateCheck do not match what is in the database.  The best way to track down which column is causing the exception is by inspecting the OriginalObject in the Updating event args.

     

    The Update parameter's ConvertEmptyStringToNull will affect both the old and new values.  You should see the difference when inspecting the OriginalObject and NewObject in the Updating event args.

     

    If the column is marked for UpdateCheck and LinqDataSource has StoreOriginalValuesInViewState enabled (the default), then the original value is the value stored by LinqDataSource during the previous Select.  Otherwise, the original value will come from the databound control, if available, using 2-way databinding.  The values stored by LinqDataSource will likely match the values from the database, whereas those coming from the databound control may have been converted to empty strings.

     

    Compare the OriginalObject values from the Updating event with those in the database to confirm which column is causing the exception.  If you need more help, feel free to send me a repro or discuss further over email: chenriks at microsoft dot com

    Tuesday, November 13, 2007 4:22 PM
  • "If the column is marked for UpdateCheck and LinqDataSource has StoreOriginalValuesInViewState enabled (the default), then the original value is the value stored by LinqDataSource during the previous Select.  Otherwise, the original value will come from the databound control, if available, using 2-way databinding.  The values stored by LinqDataSource will likely match the values from the database, whereas those coming from the databound control may have been converted to empty strings."

     

    Thanks -- this is exactly what I was looking for.  It looks like the "original" values are indeed coming from the ItemTemplate/ItemEditTemplate Label/TextBox controls, and were converted after OnSelected from null to empty string.  Adding an UpdateParameter with ConvertEmptyStringToNull="True" does now convert them back to nulls before OnUpdating -- not sure why it didn't seem to be working for me before.  Thanks for the help & info!

    Tuesday, November 13, 2007 7:12 PM
  • LinqDataSource is merging the values it gets from the databound control with what it has stored in ViewState.  In Beta2, the databound control values take precedence, but in the RTM release the values stored by LinqDataSource will take precedence.  For now, this means you will need to rely on the parameter's ConvertEmptyStringToNull property to ensure that these empty strings are converted to null values.

    Wednesday, November 14, 2007 5:46 PM
  •  

    if this error happend in LinQ to SQL

    how to deal this ?

    Wednesday, May 07, 2008 5:44 AM
  • LinqDataSource with FormView.

    Got the same exception when set readonly primary key or timestamp column in LinqToSQL designer. This properties must be writable to allow LinqDataSource create an object and set values.

    Wednesday, July 02, 2008 8:18 AM
  •  

    thanks

    I encountered the issue too and sovled the problem

    Friday, September 05, 2008 3:31 AM
  •  I solved this error by redragging over a table from the server explorer to the designer and re-building. So indeed, the designer was out-of-synch with the actual SQL Table.
    • Proposed as answer by Phil Peacock Thursday, December 17, 2009 2:03 PM
    Wednesday, February 04, 2009 7:48 PM
  • redragging worked for me. Thanks! 
    Wednesday, July 07, 2010 8:20 PM
  • Hey Guys.  I just found myself with this same exception and after scanning through this thread I notice something in my code - the varchar column in my db was marked nullable, but the field in my LINQ data context was not.  After properly marking the field as nullable to match the db everything works as normal.

    Hope this helps someone.

    • Proposed as answer by TLStutsman Tuesday, April 19, 2011 2:21 PM
    Tuesday, April 19, 2011 2:20 PM
  • I thing if you are Update perticular Records....

    you should follow this way.................................

     

     

    public bool UpdateMember(Member

    objMember)

    {

     

    DataClasses1DataContext db = new DataClasses1DataContext

    ();

    db.Members.Attach(objMember,

    true

    );

    db.Refresh(

    RefreshMode

    .KeepCurrentValues, objMember); --------------(This is Refresh Records and Update)

    db.SubmitChanges();

     

     

    return true

    ;

    }

    

    I hope ..It will Help....

    


    Chandan Sharma
    Friday, May 13, 2011 4:54 AM
  • This exception is thrown when you are retrieving the value of a field that has not yet been committed to the database.

    This can happen if you have multiple threads trying to update the same rows in the database.

    Try using a lock.

     


    Thursday, June 09, 2011 12:12 PM
  • This solution works for me :) thank you.

    byron_e

    Thursday, August 22, 2013 2:57 PM