使用不同数据上下文通过 Linq to SQL 插入和删除对象
在利用不同的数据上下文时,我在使用 Linq to SQL 向数据库插入对象或从数据库中删除对象时遇到问题。只要我使用相同的上下文插入和删除,代码就可以正常工作。但是,不能为每个函数使用相同的上下文,因为这会在代码用于 Web 服务时引入并发问题。
该代码是用 F# 编写的,但应该没有任何区别。
let CreateUser user =
use context = new Rsvp(connectionString)
context.Users.InsertOnSubmit(user)
context.SubmitChanges()
let RemoveUserById user_id =
use context = new Rsvp(connectionString)
let user = GetUser user_id
context.Users.DeleteOnSubmit(user)
context.SubmitChanges()
DeleteOnSubmit 抛出异常,如下所示:
System.InvalidOperationException:无法删除尚未附加的实体。
现在您可能认为可以将对象附加到新的数据上下文。然而这样做会导致另一个异常:
System.NotSupportedException:已尝试附加或添加不是新的实体,可能是从另一个 DataContext 加载的。不支持此功能。
我正在使用以下方法从 C# 测试项目对此进行测试
[TestMethod]
public void Can_create_and_remove_a_new_user()
{
User user = new User();
user.Name = "Test User";
user.Email = "[email protected]";
user.Role_id = 1;
UserModule.CreateUser(user);
User inserted_user = UserModule.GetUserByEmail("[email protected]");
Assert.IsNotNull(inserted_user);
UserModule.RemoveUserById(inserted_user.Id);
}
是否可以从不同的上下文中删除/插入相同的对象?
编辑: 一位朋友向我发送了这篇文章,它可以帮助解决问题,但它似乎并不是问题的最终解决方案。
I am having a problem inserting and removing objects to/from the database using Linq to SQL when utilitizing different Data contexts. The code works just fine as long as I insert and remove using the same context. However using the same context for each function is not an option as this will introduce concurrency problems as the code is used for a web service.
The code is written in F#, but it shouldn't do any difference.
let CreateUser user =
use context = new Rsvp(connectionString)
context.Users.InsertOnSubmit(user)
context.SubmitChanges()
let RemoveUserById user_id =
use context = new Rsvp(connectionString)
let user = GetUser user_id
context.Users.DeleteOnSubmit(user)
context.SubmitChanges()
An exeception is thrown from DeleteOnSubmit as follows:
System.InvalidOperationException: Cannot remove an entity that has not been attached.
Now you would think that you could just attach the object to the new data context. However doing so will cause another exception:
System.NotSupportedException: An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported.
I am testing this from a C# test project with the following method
[TestMethod]
public void Can_create_and_remove_a_new_user()
{
User user = new User();
user.Name = "Test User";
user.Email = "[email protected]";
user.Role_id = 1;
UserModule.CreateUser(user);
User inserted_user = UserModule.GetUserByEmail("[email protected]");
Assert.IsNotNull(inserted_user);
UserModule.RemoveUserById(inserted_user.Id);
}
Isn't it possible to remove/insert the same object from different contexts?
EDIT:
A friend send me this article that could help to solve the problem but it doesn't seem to be a definitive solution to the problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为这就是 DataContext 的工作原理。一个实体只能属于一个数据上下文,当您需要使用它一段时间时,您应该保留用于检索该实体的数据上下文。
如果您想尝试一些不错的功能想法,这可能是实现计算构建器以保留数据上下文(即状态单子)的好地方。然后您可以编写:
其中
getCurrentContext
是一个返回您传递的上下文的操作。可能有一些如何在 F# 中实现状态 monad 的示例。请参阅本文示例。I think that's just how
DataContext
works. An entity can belong only to a single data context and when you need to work with it for some time, you should keep the data context you used to retreive the entity.If you wanted to play with some nice functional ideas, this may be a good place to implement computation builder to keep the data context around (i.e. state monad). Then you could write:
Where
getCurrentContext
is an operation that returns the context that you're passing around. There are probably a few examples how to implement state monad in F#. See for example this article.