使用不同的数据上下文使用Linq到SQL插入和删除对象

时间:2011-03-12 18:05:45

标签: linq-to-sql exception f# datacontext

在使用不同的数据上下文时,使用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这可能有助于解决问题,但似乎并不是解决问题的明确方法。

1 个答案:

答案 0 :(得分:1)

我认为这就是DataContext的工作方式。实体只能属于单个数据上下文,当您需要使用它一段时间时,您应该保留用于检索实体的数据上下文。

如果你想玩一些不错的功能性想法,这可能是实现计算构建器以保持数据上下文(即状态monad)的好地方。然后你可以写:

let CreateUser user = datacontext {
  let! context = getCurrentContext()
  context.Users.InsertOnSubmit(user)     
  context.SubmitChanges()  }

其中getCurrentContext是一个返回您传递的上下文的操作。可能有一些例子如何在F#中实现状态monad。请参阅for example this article