跨多个方法调用共享相同的DataServiceContext - 好还是坏?

时间:2014-05-02 15:17:27

标签: c# wcf dataservice

我想知道应该如何使用DataServiceContext实例的标准做法是什么。如果我有一个有多个方法的类需要对上下文执行操作,我应该在每个方法中创建一个新的上下文实例,或者让上下文是所有方法共享的类的单个成员?

我问这个是因为我最近看到其他开发人员在我正在处理的一些代码中发表的评论提到需要在添加一些对象之后以及在对它执行更多操作之前重新创建上下文。

即。我应该这样做:

public class ServiceHelper
{
  public void DoSomething()
  {
    DataContext ctx = new DataContext(Uri);

    //do something with the context and call SaveChanges()
  }

  public int GetSometing()
  {
    DataContext ctx = new DataContext(Uri);

    return ctx.GetSomething();
   }
}

或者这个:

public class ServiceHelper
{
  private readonly DataContext _ctx = new DataContext(Uri);

  public void DoSomething()
  {
    //do something with _ctx and call SaveChanges()
  }

  public int GetSomething()
  {
    return _ctx.GetSomething();
  }
}

另外我应该补充一点,这是在ASP.NET MVC应用程序的上下文中,因此这里的ServiceHelper类将在每个页面请求上重建。

修改

好吧,根据Msft的说法似乎要么在技术上有效,因为这些都是短命的课程,但我仍然想知道两者是否同等且安全"等同的。即如果我添加/更新一些实体并调用SaveChanges,那么可能一个单独的应用程序对相同的实体进行更新,然后我使用相同的上下文实例再次检索这些实体,一切都会像我创建的那样行为相同我第二次手术前的新背景?

结论

我刚刚找到this,我认为这有助于解释差异:

  

默认情况下,客户端仅实现响应Feed中的条目   进入尚未被跟踪的实体的对象   DataServiceContext。这意味着对已经存在的对象的更改   缓存不会被覆盖。通过指定a来控制此行为   查询和加载操作的MergeOption值。这个选项是   通过在上面设置MergeOption属性来指定   DataServiceContext。默认合并选项值为AppendOnly。这个   仅实现尚未存在的实体的对象   跟踪,这意味着不会覆盖现有对象。   防止更改客户端上的对象的另一种方法   被数据服务更新覆盖的是指定   PreserveChanges。指定OverwriteChanges时,对象的值   客户端上的条目中的最新值替换为   响应源,即使已经对这些进行了更改   对象。

所以看起来如果我更新了一些实体,然后一个单独的应用程序进行了进一步的更改,然后我使用相同的DataServiceContext实例再次检索这些实体,那么它取决于MergeOption设置的内容是否会得到状态中的实体,它们在数据库中,或者只是处于我最后在本地拥有它们的状态。

1 个答案:

答案 0 :(得分:3)

Msdn says it

  

通常,DataContext实例设计为持续一个"单元   工作"但是您的应用程序定义该术语。 DataContext是   重量轻,创建起来并不昂贵。典型的LINQ to SQL   应用程序在方法范围或作为a创建DataContext实例   表示逻辑相关集的短寿类成员   数据库操作。

当然提供使用LINQ to SQL。但即使在其他技术/库中,上下文通常也是一个非常轻量级的对象。在大多数情况下,物理连接不会被拆除(但逻辑上是这样)。我猜你的问题与连接池有关,所以只要你使用一个(你应该),那么就按照msdn推荐。所以

public void DoSomething()
{
    using(DataContext ctx = new DataContext(Uri))
    {
         //do something with the context and call SaveChanges()
    }
}