2011-06-29 150 views
2

我正在关注this指南,我收到错误消息。谁能帮我?使用WCF数据服务时出错

我的数据模型的代码如下

namespace Datalayer { 
    public class DataModel { 

     public DataModel() 
     { 
      using (btWholesaleDataContext db = new btWholesaleDataContext()) { 
       //! requires auth 
       var MACRequestList = from r in db.btRequests 
            select new Models.BT.Request { 
             ID = r.ID, 
             Date = r.DateTime, 
             StatusCode = 3, 
             Status = r.Status 
            }; 

       MACRequests = MACRequestList.AsQueryable(); 

      } 
     } 

     public IQueryable<Models.BT.Request> MACRequests { get; private set; } 
    } 
} 

Web服务提供了错误

无法访问已配置 object.Object名称: 'DataContext的 处置后访问'

当我访问MACRequests

我只贴我觉得坏的代码。如果你想看更多只是让我知道。

回答

4

你的数据上下文被设置在构造函数的结尾,在using { }块的结尾。但是,当您使用IQueryable属性时,它需要基础上下文,该基础上下文已处理完毕。处理这种

一种可能的方式是让你的类IDisposable接口和配置的背景下,道:

public class DataModel : IDisposable { 

    private btWholesaleDataContext wholesaleDataContext; 

    public DataModel() 
    { 
     wholesaleDataContext = new btWholesaleDataContext(); 
     //! requires auth 
     var MACRequestList = ... ; 

     MACRequests = MACRequestList.AsQueryable(); 
    } 

    public IQueryable<Models.BT.Request> MACRequests { get; private set; } 

    public void Dispose() { 
     if(wholesaleDataContext != null) 
      wholesaleDataContext.Dispose(); 
    } 
} 

然后,你必须确保DataModel可适当用任何使用它配置。

另一种方法是使MACRequests项目,而不是IQueryable的实际名单:

public class DataModel { 

    public DataModel() 
    { 
     using (btWholesaleDataContext db = new btWholesaleDataContext()) { 
      //! requires auth 
      var MACRequestList = ... ; 

      MACRequests = MACRequestList.ToList(); // ToList reads the records now, instead of later. 

     } 
    } 

    public List<Models.BT.Request> MACRequests { get; private set; } 
} 
+0

Inisrting from IDisposable is a elegent solution。谢谢!由于即时通讯运行的网站将不断运行,DataModel将在应用程序启动并关闭时创建和处理,或者将为每个通话创建和处理? –

1

对MACRequests的查询被延期 - 一旦您不在使用块中并且您的DataContext被丢弃,您将无法进行所需的查询。

2

我认为它是因为您使用的是IQueryable <>。它懒洋洋地询问服务。 使用列表<>代替它立刻查询

或者使“btWholesaleDataContext DB”成为一个成员变量

0

你建立在你的DataModel的构造函数中使用的块数据上下文...所以由当你访问MACRequests时,数据上下文已经被处置。

考虑以下几点:

public class DataModel : IDisposable { 
    btWholesaleDataContext db = new btWholesaleDataContext(); 

    public void Dispose() 
    { 
     btWholesaleDataContext.Dipose(); 
    } 

    public IQueryable<Models.BT.Request> MACRequests { 
      get { 
           return from r in db.btRequests 
           select new Models.BT.Request { 
            ID = r.ID, 
            Date = r.DateTime, 
            StatusCode = 3, 
            Status = r.Status 
           }; 
      } 
    } 
} 

注意,这种用法将工作:

using (var dm = new DataModel()) 
{ 
    dm.MACRequests.ToArray(); 
} 

但这将失败出于同样的原因为原:

IQueryable<Models.BT.Request> requests = null; 

using (var dm = new DataModel()) 
{ 
    requests = dm.MACRequests; 
} 

// this will fail because the context is disposed by the time we force enumeration of the query 
requests.ToArray(); 

.. 。或者,由于WCF数据服务无法在预测上过滤,因此您可以真正使用查询

         from r in db.btRequests 
            select new Models.BT.Request { 
             ID = r.ID, 
             Date = r.DateTime, 
             StatusCode = 3, 
             Status = r.Status 
            }; 

执行它...

只是考虑更改您的原始代码来返回一个数组或列表,而不是将其作为查询。