使用WCF数据服务时出错

发布于 2024-11-18 02:31:20 字数 1109 浏览 3 评论 0原文

我正在遵循指南,但收到错误。有人可以帮助我吗?

我的数据模型的代码如下

  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 处置后访问。

当我访问 MACRequests 时

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

I'm following this guide and I am getting an error. Can anyone help me?

The code for my datamodel is below

  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; }
    }
}

The web service gives the error

Cannot access a disposed
object.Object name: 'DataContext
accessed after Dispose.'

When I access MACRequests

I have only posted the code I think is broken. If you want to see more just let me know.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蔚蓝源自深海 2024-11-25 02:31:20

您的数据上下文将在构造函数的末尾、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; }
}

Your data context is being disposed at the end of your constructor, at the end of the using { } block. However when you use the IQueryable MACRequests property, it needs that underlying context, which has since been disposed.

One possible way to handle this is to make your class IDisposable and dispose the context that way:

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();
    }
}

Then you have to make sure that DataModel is properly disposed by whatever uses it.

Another alternative is to make MACRequests the actual list of items instead of the 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; }
}
毁虫ゝ 2024-11-25 02:31:20

我认为这是因为您正在使用 IQueryable<>。它懒惰地查询服务。
使用列表<>相反,以便它立即查询

或将“btWholesaleDataContext db”放入成员变量

I think its because you are using an IQueryable<>. Its lazily queries the service.
Use List<> instead so that it queries immediately

Or make "btWholesaleDataContext db" into a member variable

回心转意 2024-11-25 02:31:20

对 MACRequests 的查询被推迟 - 一旦您脱离了 using 块并且您的 DataContext 被释放,您将无法进行您想要的查询。

Queries to MACRequests are deferred - once you're out of the using block and your DataContext is disposed you're not going to be able to make the query you want.

情未る 2024-11-25 02:31:20

您正在 DataModel 构造函数的 using 块中创建数据上下文...因此,当您访问 MACRequest 时,数据上下文已被释放。

请考虑以下事项:

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
                                     };

是执行它...

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

You're creating the data context in a using block in the constructor of your DataModel...so by the time you access the MACRequests, the data context has been disposed.

Consider the following:

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
                                 };
          } 
    }
}

Note that this usage will work:

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

but this will fail for the same reason as the original:

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();

...Alternatively, since WCF data services can't filter on projections, and thus all you can really do with the query

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

is execute it...

just consider changing your original code to return an array or a list instead of leaving it as a queryable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文