无法访问Disposed对象MVC4 View

时间:2013-02-13 10:27:57

标签: c# asp.net-mvc-3 asp.net-mvc-4

我正在开发一个系统,它将使用大量的下拉和重复列表。因此,为了避免重复代码我创建了DropDownManagerClass(),这将允许我从系统中的任何位置调用Customers下拉列表:

public class DropDownManager:BaseManagerClass
{
    public DropDownManager(String connectionString)
        : base(connectionString)
    {
    }

    public IEnumerable<SelectListItem> GetCustomerDD()
    {

        this.OpenConnection();

        IEnumerable<SelectListItem> dropDown = this._context.Customers.Select(m => new SelectListItem { Text = m.Description, Value = m.CustomerID.ToString() });

        this.CloseConnection();

        return dropDown;


    }

}

然后我通过调用一次性管理器类来填充我的模型,您将看到我正在处理该对象以清理与数据库的连接。

  DropDownManager dropdown = new DropDownManager(Global.ConnectionString);

  IEnumerable<SelectListItem> customers = dropdown.GetCustomerDD();
  IEnumerable<SelectListItem> suppliers= dropdown.GetSuppliersDD();

  model.CustomersDD= customers;
  model.SuppliersDD= suppliers;

  dropdown.Dispose();

当我调试时,我注意到客户和供应商都有一个SQL语句。因此,当谈到我的观点时,我认为这是尝试执行SQL来获取数据的地方,但是我已经处理dropdown它正在抛出错误。如果我删除dropdown.Dispose(),则代码可以正常工作。

我的观点

@Html.DropDownListFor(m => m.Customer.CustomerID, Model.CustomersDD, new { @class = "large" })

无论如何,我可以用数据填充我的模型并有效地处理这个经理吗?

修改当我从客户中选择后调用.ToList()时,我可以看到模型现在已经在视图中显示了结果集,但它仍然给出了错误

6 个答案:

答案 0 :(得分:1)

我不知道这是否会起作用,buuut ....您是否尝试过使用“using”语句而不是手动调用.Dispose()?

http://msdn.microsoft.com/en-us/library/yh598w02.aspx

答案 1 :(得分:1)

你可以试试下面的代码吗?这是我在这里提出的建议以及如何编写代码的组合:

首先替换您的GetCustomerDD()

public List<SelectListItem> GetCustomerDD()
{
    List<SelectListItem> dropDown;
    try
    {
        OpenConnection();

        // .ToList() here makes sure you get the result immidiately
        dropDown = _context.Customers.Select(m => new SelectListItem { Text = m.Description, Value = m.CustomerID.ToString() })
            .ToList();              
    }
    finally
    {   
        // try-finally makes sure you always close your connection
        CloseConnection();
    }
    return dropDown;
}

然后这样称呼:

using (var dropDownManager = new DropDownManager(Global.ConnectionString))
{  
    // using makes sure the DropDownManager is always disposed
    CustomersDD = dropDownManager.GetCustomerDD();
}

这有用吗?

顺便说一句;在您的帖子中,您声明您已将DropDownManager置于关闭状态,但在您的代码中,您似乎关闭了与this.CloseConnection()GetCustomerDD()的关联。我们错过了什么吗?也许你不需要把它丢弃来关闭连接?

答案 2 :(得分:0)

问题是查询仅在您开始枚举结果(稍后)时才执行,但是,当您在枚举结果之前处置下拉列表时,然后当您尝试稍后枚举它们时,查询将针对上下文运行已经处理并失败。

您应该在请求中稍后处理上下文,或者在处理请求之前枚举查询(调用列表)以避免此问题。

答案 3 :(得分:0)

您可能已经尝试过,但是您是否尝试将IENumerable更改为List:

List<SelectListItem> customers = dropdown.GetCustomerDD().ToList();
List<SelectListItem> suppliers = dropdown.GetSuppliersDD().ToList();

答案 4 :(得分:0)

您是否考虑过循环并将它们添加到列表中,希望在将数据库传递给视图之前查询数据库?

var list = new List<SelectListItem>();

this._context.Customers
    .Select(m => new SelectListItem { Text = m.Description, Value = m.CustomerID.ToString() })
    .ForEach(x => list.Add(x));

真的是一般的想法。祝你好运!

答案 5 :(得分:0)

如果你在using语句中使用Linq2Entity或Linq2Sql(顺便说一下这是最好的方法),在你真正访问数据之前不会执行查询(绑定,使用First,Count,ToList或任何其他方法)获取数据)。

您只需要调用Utils类中的ToList()方法来“实现”结果。在DropdownManagerClass中进行操作非常重要,而不是在外部。