2

我正在开发一个系统,它将使用大量的下拉列表和重复列表。因此,为了避免重复代码,我创建了一个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()从客户那里选择之后打电话时,我可以看到模型现在有结果集,但在视图中它仍然给出错误

4

6 回答 6

1

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

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

于 2013-02-20T14:37:35.267 回答
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()inside的连接GetCustomerDD()。我们错过了什么吗?也许您不需要处理它来关闭连接?

于 2013-02-21T13:11:18.103 回答
0

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

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

于 2013-02-15T01:04:29.137 回答
0

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

List<SelectListItem> customers = dropdown.GetCustomerDD().ToList();
List<SelectListItem> suppliers = dropdown.GetSuppliersDD().ToList();
于 2013-02-17T22:29:52.923 回答
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));

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

于 2013-02-20T16:49:21.067 回答
0

如果您在 using 语句中使用 Linq2Entity 或 Linq2Sql(通常是最好的方法),则在您真正访问数据(绑定、使用 First、Count、ToList 或任何其他获取数据)。

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

于 2013-02-21T10:59:52.800 回答