Tuesday, May 27, 2008

LinqDataSource error on Update or Insert

Here is a reminder for myself about a problem that happens, and I always end up having to search to remember the solution. When performing an update or insert on a LinqDataSource, say from a GridView you get the error "Could not find a row that matches the given keys in the original values stored in ViewState. Ensure that the 'keys' dictionary contains unique key values that correspond to a row returned from the previous Select operation."... Sounds complicated.

Well it isn't. Check that you have set the DataKeyNames property on the GridView with the column name of the primary key(s) of the LinqDataSource table. But that doesn't make sense, you say.

It does if you have a look at the stack trace. For example,
System.Web.UI.WebControls.LinqDataSourceView.GetOriginalValues(IDictionary keys) +926 System.Web.UI.WebControls.LinqDataSourceView.BuildUpdateDataObjects(Object table, IDictionary keys, IDictionary values, IDictionary oldValues) +102 System.Web.UI.WebControls.LinqDataSourceView.ExecuteUpdate(IDictionary keys, IDictionary values, IDictionary oldValues) +87 System.Web.UI.DataSourceView.Update(IDictionary keys, IDictionary values, IDictionary oldValues, DataSourceViewOperationCallback callback) +78

The LinqDataSource is just like the old SqlDataSource - it needs to know how to lookup the row in the database table to work out what you have changed. If you don't tell it the keys to lookup in the table, how will it ever know which row you were editing? Once the DataKeyNames are specified those columns are used to find the original row in the database, compare and merge your update changes and commit them back to the row. Simple. Now I just have to remember "Set the DataKeyNames property"...

kick it on DotNetKicks.com Shout it

Tuesday, May 20, 2008

Windows Workflow still immature

I have been spending the last couple of weeks looking at how to integrate Microsoft Windows Workflows into my ASP.Net website. It is a basic usage of workflow - implement a state machine, do some processing on state initialisation, maybe fire an email or reminder here and there. It all sounds great on the surface and it basically works. But there are a few things that will just mean that it isn't workable in my site.

You see I have long running workflows, let's say longer than a week. They might hang around waiting for user input, a client to phone back, fill in a web form or something of that nature. However I am taking an agile approach to this particular development - releasing little functionality increments for the client. The problem is that workflows are tied to assembly versions, and my assembly versions are changing all the time. Not to mention that the workflow structure is also changing all the time.

So what do I do? Something like Ruurd Boeke suggests could pass, but hell that is a lot of work, considering I'll be doing this every two weeks or so. I don't have a good solution, so for the moment it is shelved. I'll just implement a basic state flag on my object and then provide a generic mechanism for faking the state flow. If things are designed right then I should be able to reuse any code in workflow activities once it all gets running. I'll try to use workflows for some of the short tasks that are required, just to make sure I am still getting my feet wet with the technology.

This seems like a typical trend for Microsoft to release something that is really, really beta (nay, alpha?) to gauge public opinion and then develop it a production standard later on. Windows workflows seem to me like they are nowhere near ready for production systems.

Do you have an opinion??

kick it on DotNetKicks.com Shout it