开发者

Linq to Sql: ChangeConflictException not being thrown (and no rows updated/deleted)

开发者 https://www.devze.com 2023-02-01 15:19 出处:网络
I\'m trying to fit Linq to Sql into an N-Tier design. I am implementing concurrency by supplying original values when attaching objects to the data-context. When calling SubmitChanges, and observing t

I'm trying to fit Linq to Sql into an N-Tier design. I am implementing concurrency by supplying original values when attaching objects to the data-context. When calling SubmitChanges, and observing the generated scripts on sql server profiler, I can see that they are being generated properly. They include where clauses that check all the object properties (they are all marked with UpdateCheck.Always).

The result is as expected, i.e., no rows are updated on updates or deleted on deletes. Yet I am not getting any exception. Isn't this supposed to throw a ChangeConflictException?

For clarity here is the design and flow for the tests I'm running: I have a client console and a service console talking to each other via WCF using WsHttpBinding.

  1. Client requests data from service
  2. Service instantiates a datacontext, retrieves data, disposes context, returns data to client.
  3. Client makes modifications to returned data.
  4. Client requests an update of changed data from the ser开发者_如何学Govice.

    5a. Service instantiates a datacontext, attaches objects, and...

    5b. I pause execution and change values in the database in order to cause a change-conflict

    5c. Service calls SubmitChanges.

Here's the code for step 5, cleaned up a bit for clarity:

public void UpdateEntities(ReadOnlyChangeSet<Entity> changeSet)
        {
            using (EntityDataContext context = new EntityDataContext())
            {
                if (changeSet.AddedEntities.Count > 0)
                {
                    context.Entities.InsertAllOnSubmit(changeSet.AddedEntities);
                }

                if (changeSet.RemovedEntities.Count > 0)
                {
                    context.Entities.AttachAll(changeSet.RemovedEntities, false);
                    context.Entities.DeleteAllOnSubmit(changeSet.RemovedEntities);
                }

                if (changeSet.ModifiedRecords.Count > 0)
                {
                    foreach (var record in changeSet.ModifiedRecords)
                    {
                        context.Entities.Attach(record.Current, record.Original);
                    }
                }

                // This is where I pause execution and make changes to the database

                context.SubmitChanges();
            }
        }

I'm using some classes to track changes and maintain originals, as you can see.

Any help appreciated.

EDIT: I'm having no problems with inserts. I've only included the code that calls InsertAllOnSubmit for completeness.


So I've found the answer. It appears to be a bug in Linq To Sql (correct me if I'm wrong). It turns out that the table being updated in the database has a trigger on it. This trigger calls a stored procedure that has a return value. This causes calls to insert, update or delete on this table to yield a return value (from the stored procedure run by the trigger) which is NOT a row-count but is a number. Apparently L2S sees this number and assumes all went well even though no insert/update/delete actually occurred.

This is quite bizarre, especially considering the returned number has a defined column name and its value is in the 6-digit area.

0

精彩评论

暂无评论...
验证码 换一张
取 消