Paymentsense / Dapper.SimpleSave

Saving of new and updated data using Dapper
MIT License
31 stars 12 forks source link

Sometimes appears to emit duplicate columns in SET clause of UPDATE statement #20

Closed bartread closed 9 years ago

bartread commented 9 years ago

Report from paulmc, who is getting the following error:

The column name 'UpdateDate' is specified more than once in the SET clause or column list of an INSERT. A column cannot be assigned more than one value in the same clause. Modify the clause to make sure that a column is updated only once. If this statement updates or inserts columns into a view, column aliasing can conceal the duplication in your code.

A dig through loggly found the following fragment:

UPDATE [gen].PHONE_NUMBER_MST\r\nSET [UpdateDate] = @p3,\r\n [UpdateDate] = @p4\r\nWHERE [PhoneGuid] = @p5;\r\n\r\nwith parameters:\r\n{\"p0\":\"2015-03-24T10:45:57.4082+00:00\",\"p1\":\"86030ec5-12d2-e411-93f8-0cc47a07ef4a\",\"p2\":{\"Delegate\":{},\"target0\":{\"command\":{\"Operations\":[{\"ColumnName\":\"UpdateDate\",\"Owner\":{\"EmailAddressGuid\":\"825089f3-12d2-e411-93f8-

At the time I wasn't sure why this might be happening and suspected some issue with a [Column] attribute being deployed incorrectly on a property.

However, I've now found this in CommandBuilder:

               if (operation is UpdateOperation)
               {
                   var update = operation as UpdateOperation;
                   //  If the table name, or row PK changes, we need to apply any UpdateOperations we already have as a new command
                   //  then start tracking UpdateOperations afresh, starting with this one.
                   if (updateTableName != update.TableName || !PrimaryKeyComparer.SuppliedPrimaryKeyValuesMatch(update.OwnerMetadata, updatePk, update.OwnerPrimaryKeyAsObject))//updatePk != update.OwnerPrimaryKey)
                   {
                       ValidateUpdateOperation(update);
                       if (null != updateTableName)
                       {
                           ApplyUpdatesSoFarAsNewCommand(results, updates, ref updateTableName, ref updatePk);
                       }

                       updateTableName = update.TableName;
                       updatePk = update.OwnerPrimaryKeyAsObject;
                   }
                   updates.Add(update);
               }
               else
               {
               ...

Basically it always ends up using the parent table name to figure out whether it should move on to a new UPDATE command, even if in some cases the update is on a child table. I think this may be causing the problem because updates across two tables are being conflated into a single update.