强制执行单一默认操作

时间:2013-08-09 02:37:29

标签: asp.net-mvc-4 asp.net-web-api

任何人都可以告诉我为什么以下代码在api控制器(MVC4)中不起作用?我收到一条错误消息,说“无法访问已处置的对象”。我发现在其他情况下应该调用ToList(),以便强制执行查询。但在我的情况下,我正在使用SingleOrDefault(),这不是马上在数据库上执行的吗?

    public HttpResponseMessage GetPurchaseOrder(int POId)
    {
        PurchaseOrder po;
        HttpResponseMessage resp;

        using (PMDataDataContext database = new PMDataDataContext())
        {
            po = database.PurchaseOrders.SingleOrDefault(x => x.POId == POId);
            if (po == null)
            {
                var message = string.Format("id = {0} not found", POId);
                HttpError err = new HttpError(message);
                resp = Request.CreateResponse(HttpStatusCode.NotFound, err);                    
            }
            else
            {
                resp = Request.CreateResponse(HttpStatusCode.OK, po);
            }
        }
        return resp;
    }

3 个答案:

答案 0 :(得分:0)

尝试以便在查询之后立即处理数据库的上下文。 SingleOrDefault应立即将查询发送到数据库。

public HttpResponseMessage GetPurchaseOrder(int POId)
{
    PurchaseOrder po;
    HttpResponseMessage resp;

    using (PMDataDataContext database = new PMDataDataContext())
    {
        po = database.PurchaseOrders.SingleOrDefault(x => x.POId == POId);
    }

    if (po == null)
    {
        var message = string.Format("id = {0} not found", POId);
        HttpError err = new HttpError(message);
        resp = Request.CreateResponse(HttpStatusCode.NotFound, err);                    
    }
    else
    {
        resp = Request.CreateResponse(HttpStatusCode.OK, po);
    }

    return resp;
}

答案 1 :(得分:0)

是的,但是如果PurchaseOrder中有任何延迟加载的属性,当Web API尝试序列化对象时,EF将尝试从数据库中获取数据,为此需要上下文,但是将无法使用。

答案 2 :(得分:0)

巴德里带领我解决了我的问题。当我在我的代码中放置断点并在调试模式下跟随时,似乎其中一个关联对象需要获取上下文。当我查看相关属性时,属性PurchaseOrder.Item.ItemCategory给出了ObjectDisposedException。

我通过在使用SingleOrDefault调用获取po之前放置database.DeferredLoadingEnabled = false来解决它。