使用WCF数据服务时出错

本文关键字:出错 服务 数据 WCF 使用 | 更新日期: 2023-09-27 18:00:37

我正在遵循本指南,但我遇到了一个错误。有人能帮我吗?

我的数据模型的代码低于

  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服务提供错误

无法访问已释放的对象对象名称:'DataContext在Dispose之后访问。'

当我访问MAC请求时

我只发布了我认为已损坏的代码。如果你想看更多,请告诉我。

使用WCF数据服务时出错

您的数据上下文将在构造函数的末尾,即using { }块的末尾进行处理。但是,当您使用IQueryable MACRequests属性时,它需要该基础上下文,该上下文已被释放。

处理这一问题的一种可能方法是使类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; }
}

我认为这是因为您使用的是IQueryable<>。它懒散地查询服务。使用列表<>以便它立即查询

或者将"btWholesaleDataContext db"设置为成员变量

对MACRequest的查询被推迟-一旦您退出使用块并处理了DataContext,您就无法进行所需的查询。

您正在DataModel的构造函数中的using块中创建数据上下文。。。因此,当您访问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
                                     };

就是执行它…

只需考虑更改原始代码以返回数组或列表,而不是将其保留为可查询的。