I am trying to force a ChangeConflictException by altering records in two different browsers. This has worked for me in the past. But now it just wont throw the exception.
Last one in is winning.
I have checked the column properties of the entity I am updating and each column is set to always check.
Is there anything I can look for?
I haven't extended this data context or done any modifications to any of the properties.
Thanks.
EditThis is an ASP.net application.
Are you sure this is not what is happening:
Browser A loads entity X
Browser B loads entity X
Browser A submits form
Browser A loads entity X again, changes property and stores again
Browser B submits form
Browser B loads entity X again, changes property and stores again
Key point here is that the entity is reloaded on postback (HTTP = stateless) and in 6) you are actually loading changes made by 4) and overwriting them. Linq2Sql does not "stamp" your form you would have to do this manually.
You write in the comments that you have another app that works. If that is a Windows app, then the situation is completely different, since the entity is then most likely not reloaded again.
That's a race condition. Consider you are probably retrieving the info, updating and sending to the db. If the first commits the changes to the db, before the second retrieves the info you wouldn't get a conflict.
Update: About the comment on not being able to do it. You can do it, you use the Attach method but you need to keep any original values you want it to check for the concurrency. Check these:
linq2sql-update-object-not-created-in-datacontext
how-to-update-a-single-column-in-linq-without-loading-the-entire-row
That is surely what is happening under the linq datasource.
Related
I am using VS 2013 Express for Web with ADO.NET Entity Data Model.
When updating the entity data model from database using 'refresh' tab option (seems you can only select one item though the heading says select objects plural) the usage seems unclear and I have noticed some issues.
Just two examples:
I changed a stored procedure so it returned the same number of fields but one field was of a slightly different type but the complex type never changed. I realise there can be an impact on client code but this simply did not change the complex type, everything stayed the same. However, removing the relevant elements from the model browser then readding the elments from the database back into the model did exactly what I expected.
I made some significant changes to two or three tables, attributes and one relationship but did bot change the table names. Here again refresh had some very odd results, so I simply created a fresh model.
I am planning some more changes first change specifically I am adding a FK relationship that I forgot.
Is there any way to be sure of what is supported and what is not in terms of refresh.
Also I am concerned that if refresh fails and I so delete the two tables with the relationship, what impact will that have on temporarily orphaned tables and their relationships, and if when I regenerate the two tables their connections with the other tables will still work. I guess it depends how the generated code works underneath.
I want to make these kinds of changes but avoid have to recreate the entire model.
Any advice appreciated.
The most guaranteed way of ensuring you always have the latest version is to select all (Ctrl A) delete, and then re-add everything from the model page.
I know it sounds like a pain but it's guaranteed to work as long as you haven't made any changes to the model from within Visual Studio.
The refresh doesn't always work.
I haven't been able to find anything that addresses my problem. Here's the scenario. We have an application that generates lists of entities in memory (List) when the application starts. As long as data manipulation is done from within this application, changes are persisted to the database and back to the client application just fine. However, we've encountered a case where the database record that an entity is mapped to in memory of the application could be modified elsewhere outside of the application. These changes aren't seen until the application terminates and is restarted. Could somebody point me in the right direction on how to take an existing entity (or list of entities) and "refresh" the property values with any possible changed values in the underlying database record that it is mapped to?
Entity Framework has a "Refresh" method built into it (see MSDN article here). I think the refresh mode you would want is "Store wins". This will reset all your values in your application with what is currently stored in the DB.
I'm not able to identify any specific code for this problem, but I'll describe the setup and the problem and see if I can get any answers.
User object, contains Profile record. Profile record contains Template record.
On user login, I hold this user object in session.
When I need, I ask about access rights from the template record.
This is working perfectly in MOST cases. I can login, works fine. Another user (set to a different access template) logs in and the first access right check fails because it reports the Object Context is disposed. I change the access template to the same as me, all works fine. I change my access template to be the one that's breaking on the other user and it works fine. The stack trace doesn't identify anything else. The Profile record (also an associated record) is fully populated, there are other associations on the profile record that work just fine.
Summary;
Me without changes, works fine.
Other user without changes, crashes.
Me with same exact setup as other user, works fine.
Other user with my setup works fine.
I'm not sure what to look at, I can't identify any particular failing code so I don't think the method is bad. If I debug while logging in as the broken user, it doesn't break anymore.
Does anybody have any suggestions, advice or information I can provide? I don't know if it helps to know I'm using MVC3, but I've tagged it there just in case.
Update: Thank-you for the input. I have got a solution, but I can't explain it.
Table A contains association with Table B
Table C contains association with Table B (Table B has NO association with C or A )
By changing records in C, I could fix the issue, there was consistency in that I could change the records to match a broken user and my user would break. If I changed the records back, it would work again for me. My login process makes mention of table C, but does not set any data or change the behavior of the loading of profile from table A.
If I prevent the lazy load of B; TableA.Include(TableB) the problem goes away regardless of what is in table C.
Why would the lazy load work in some cases but not others? The records that Table C contained were all valid in both failure and success cases, and there was no direct change of A based on any query of C.
I know that the only way for someone to really have an answer to this is to see the code, which I can't share, but if anybody has any ideas or has seen this behavior before, I would appreciate any insight.
I have very standart scenario. I send entity from controller to view for user to edit it. User pushes submit button I get entity back from browser in my controller. Its detached now so I attach it back to context. How can I detect if there were changes made compared to database?
You need to pull the entity back from the database when the user submits. There are a number of reasons you can't know for certain what to do just by looking at what came back:
Can't trust data from the user. The user has full control over what the browser sends back to you, so this is a possible exploit if you key off something in the request
Another user might have modified the same data
Pulling an entity from the database is fast, so just pull it, set the fields you want to set and SaveChanges()
Addition: As Eduard noted in the comments below, it looks like there is a utility method ApplyCurrentValues to do this: msdn.microsoft.com/en-us/library/dd487246.aspx
Sorry, if this is a duplicate. Please point me to the appropriate question if this is but I could not find exactly what I am looking for.
So I am using a Linq to SQL datacontext for entity tracking and persistence in an ASP.NET web application. It is for an Intranet application that does not have a ton of users at a time. Right now I cam storing the datacontext in session state, which makes me feel dirty! It seems like I need the context always to be present though because I need to preserve the change tracking on the entities that are being modified. All of our screens have a Save button that would then call SubmitChanges() on the DataContext and persist all of the pending changes in memory.
Should I be storing the DataContext? Should I be disposing of it at the end of each request and then recreate it somehow and get the pending changes? If I should recreate it every time, I dont understand how the context could know what has changed without a ton of redundant database hits on each request.
First, I would say to stop putting things in Session altogether. Especially if you don't have a lot of users, just load the data when you need it.
Don't store the data context at all. Just create a new one on each page when you need it. When they hit the Save button, recreate a data context, load the object from the database, make the changes necessary based on the form input, and then save it back to the database. It should just be two database hits for each object, one to load, and then one to save it back.
I think the best practice with the data context is the Unit of Work pattern, where the scope of the Unit of Work is the single request that you are servicing. Instantiate a new data context each time you need to make changes. If you're concerned about overwriting changes that have been made after drawing the previous page, then consider using and persisting a version/timestamp in a hidden field and checking it against that returned from the data context when retrieving the entity to update.