首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用无争用条件的实体框架实现if-not-exists insert

使用无争用条件的实体框架实现if-not-exists insert
EN

Stack Overflow用户
提问于 2010-11-16 07:43:04
回答 2查看 7.2K关注 0票数 15

使用LINQ-to-Entities 4.0,是否有正确的模式或构造来安全地实现“如果不存在则插入”?

例如,我目前有一个跟踪“用户收藏”的表格--用户可以在收藏列表中添加或删除文章。

基础表不是真正的多对多关系,而是跟踪一些附加信息,例如添加收藏夹的日期。

代码语言:javascript
复制
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);

根据需要,插入具有相同用户/文章对的两个收藏夹会导致重复的键错误。

我目前已经使用C#在数据层实现了“如果不存在,那么插入”逻辑:

代码语言:javascript
复制
if (!entities.FavoriteArticles.Any(
        f => f.UserId == userId && 
        f.ArticleId == articleId))
{
    FavoriteArticle favorite = new FavoriteArticle();
    favorite.UserId = userId;
    favorite.ArticleId = articleId;
    favorite.DateAdded = DateTime.Now;

    Entities.AddToFavoriteArticles(favorite);
    Entities.SaveChanges();
}

这个实现的问题是它容易受到竞争条件的影响。例如,如果用户双击“添加到收藏夹”链接,则会向服务器发送两个请求。第一个请求成功,而第二个请求(用户看到的请求)失败,UpdateException包装了重复键错误的SqlException。

使用T-SQL存储过程,我可以使用带有锁提示的事务,以确保不会出现争用条件。有没有一种干净的方法来避免实体框架中的竞态条件,而不求助于存储过程或盲目地吞噬异常?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-19 04:05:33

您可以尝试将其封装在一个事务中,并结合“著名的”try/catch模式:

代码语言:javascript
复制
using (var scope = new TransactionScope())
try
{
//...do your thing...
scope.Complete();
}
catch (UpdateException ex)
{
// here the second request ends up...
}
票数 -3
EN

Stack Overflow用户

发布于 2011-04-23 03:47:25

还可以编写使用sql 2005+中的一些新技巧的存储过程。

在update语句中使用您的组合唯一ID (userID + articleID),然后使用@@RowCount函数查看行数是否大于0如果它是1(或更多),则更新找到了与您的userID和ArticleID匹配的行,如果它是0,则可以插入。

例如:

更新tablex集合userID = @ userID,ArticleID = @ArticleID (您可以在这里拥有更多属性,只要where包含一个组合的唯一ID),其中UserID= @UserID和ArticleID = @ArticleID

如果(@@RowCount = 0) Begin Insert Into ...结束

最棒的是,这一切都是在一个调用中完成的,所以您不必先比较数据,然后再决定是否应该插入。当然,它将停止任何迟钝的插入,并且不会抛出任何错误(优雅地?)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4189954

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档