Note that there are some explanatory texts on larger screens.

plurals
  1. POImplementing if-not-exists-insert using Entity Framework without race conditions
    primarykey
    data
    text
    <p>Using LINQ-to-Entities 4.0, is there a correct pattern or construct for safely implementing "if not exists then insert"?</p> <p>For example, I currently have a table that tracks "user favorites" - users can add or remove articles from their list of favorites.</p> <p>The underlying table is not a true many-to-many relationship, but instead tracks some additional information such as the date the favorite was added.</p> <pre><code>CREATE TABLE UserFavorite ( FavoriteId int not null identity(1,1) primary key, UserId int not null, ArticleId int not null ); CREATE UNIQUE INDEX IX_UserFavorite_1 ON UserFavorite (UserId, ArticleId); </code></pre> <p>Inserting two favorites with the same User/Article pair results in a duplicate key error, as desired. </p> <p>I've currently implemented the "if not exists then insert" logic in the data layer using C#:</p> <pre><code>if (!entities.FavoriteArticles.Any( f =&gt; f.UserId == userId &amp;&amp; f.ArticleId == articleId)) { FavoriteArticle favorite = new FavoriteArticle(); favorite.UserId = userId; favorite.ArticleId = articleId; favorite.DateAdded = DateTime.Now; Entities.AddToFavoriteArticles(favorite); Entities.SaveChanges(); } </code></pre> <p>The problem with this implementation is that it's susceptible to race conditions. For example, if a user double-clicks the "add to favorites" link two requests could be sent to the server. The first request succeeds, while the second request (the one the user sees) fails with an UpdateException wrapping a SqlException for the duplicate key error.</p> <p>With T-SQL stored procedures I can use transactions with lock hints to ensure a race condition never occurs. Is there a clean method for avoiding the race condition in Entity Framework without resorting to stored procedures or blindly swallowing exceptions? </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload