在实体框架中以事务方式获取或创建数据库对象

发布于 2024-11-28 16:26:28 字数 779 浏览 2 评论 0原文

我正在使用 Entity Framework 4.1,并且有一个看似简单的要求:我想通过唯一键获取一个实体,或者如果它尚不存在,则创建它:

        var user = db.Users.SingleOrDefault(u => u.Sid == sid);
        if (user != null)
            return user;

        user = new User(sid);
        db.Users.Add(user);

通常这工作正常,但是当我运行一堆时一起测试(使用 MSTest),其中之一始终失败,并显示“序列包含多个元素”。当我单独运行该测试时,它工作得很好。

问题似乎很明显:多个线程同时调用上述代码,每个线程创建一个新的用户行。但解决办法是什么?

当然,正确的解决方案是事务,但我就是无法让它发挥作用。如果我启动一个普通的 DbTransaction,EF 将不会使用它。如果我使用 TransactionScope,它要么没有效果(发生相同的错误),要么 EF 尝试启动分布式事务但失败,即使我遵循 有关首先打开连接的建议

这确实令人沮丧,因为对于普通的旧 SQL 来说,这是一件非常琐碎的事情:开始事务、SELECT、INSERT、提交事务。我怎样才能让它在 EF 中工作?它不必使用事务——无论它如何工作。

I'm using Entity Framework 4.1 and have a seemingly simple requirement: I want to either get an entity by a unique key, or if it doesn't already exist, create it:

        var user = db.Users.SingleOrDefault(u => u.Sid == sid);
        if (user != null)
            return user;

        user = new User(sid);
        db.Users.Add(user);

Normally this works fine, but when I run a bunch of tests together (using MSTest) one of them consistently fails with "Sequence contains more than one element". When I run that test by itself it works fine.

The problem seems obvious: multiple threads are calling the above code concurrently and each create a new User row. But what is the solution?

The proper solution is a transaction, of course, but I just cannot get it to work. EF won't use a normal DbTransaction if I start one. If I use a TransactionScope it either has no effect (the same error occurs) or EF tries and fails to start a distributed transaction, even if I follow the advice about opening a connection first.

This is really frustrating, because it is such a trivial thing to do with plain old SQL: begin transaction, SELECT, INSERT, commit transaction. How can I get this to work in EF? It doesn't have to be using transactions - whatever makes it work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

源来凯始玺欢你 2024-12-05 16:26:29

如果您的数据库对 SidUNIQUE 约束,第一个语句(唯一可能导致您描述的错误的语句)将永远不会失败。是吗?它应该。这是确保 sid 真正全局唯一的唯一方法。

The first statement (the only one which could cause the error you describe) will never fail if your DB has a UNIQUE constraint on Sid. Does it? It should. That's the only way to make sure that the sid is truly, globally unique.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文