在使用不同的数据上下文时,使用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 = "test@mail.com";
user.Role_id = 1;
UserModule.CreateUser(user);
User inserted_user = UserModule.GetUserByEmail("test@mail.com");
Assert.IsNotNull(inserted_user);
UserModule.RemoveUserById(inserted_user.Id);
}
是否可以从不同的上下文中删除/插入相同的对象?
编辑: 朋友寄给我this article这可能有助于解决问题,但似乎并不是解决问题的明确方法。
答案 0 :(得分:1)
我认为这就是DataContext
的工作方式。实体只能属于单个数据上下文,当您需要使用它一段时间时,您应该保留用于检索实体的数据上下文。
如果你想玩一些不错的功能性想法,这可能是实现计算构建器以保持数据上下文(即状态monad)的好地方。然后你可以写:
let CreateUser user = datacontext {
let! context = getCurrentContext()
context.Users.InsertOnSubmit(user)
context.SubmitChanges() }
其中getCurrentContext
是一个返回您传递的上下文的操作。可能有一些例子如何在F#中实现状态monad。请参阅for example this article。