由于我仍然希望得到答案,我想重新说明我的问题。假设我有一个 GUI,其中有两个列表,一个显示数据库 tblOrders 中所有条目的列表,另一个显示每个订单中的项目。
我可以使用 Linq2sql 或 EF 从数据库中获取所有订单,如下所示:
using (DataClasses1DataContext DataContext = new DataClasses1DataContext())
ListOfOrders = DataContext.tblOrder.ToList();
我可以把这些订单以列表或
datagridview
的形式显示出来。然后,在选择其中一个工作时,我想要访问表格tblItems
中的实体集合。我可以这样做:ListOfOrders.First().tblItems.toList();
除非我需要已被处理的
DataContext
,否则我无法做到这一点。从某种意义上讲,这是有道理的,因为我无法保证自从我检索ListOfOrders
以来是否添加了新项目到该订单中。因此,理想情况下,我想检查tblOrder.tblItems集合是否有添加,并且仅在必要时从服务器重新检索该集合。
背景是,我的模型有点复杂:它由订单组成,每个订单又由零件组成,每个零件又由任务组成。因此,要评估每个订单的进度,我必须检索属于订单的所有零件,并针对每个零件查看已完成多少任务。在具有200个作业,每个作业都有1到10个零件的数据库中,这简单地使我的程序响应速度过慢...
有人能帮我吗?
原始问题
我找到了很多关于DataContext
的问题,但我还没有找到解决我的问题的方法。如果我执行以下操作:
using (DataClasses1DataContext DataContext = new DataClasses1DataContext())
ListOfOrders = DataContext.tblOrder.ToList();
这给我一个
tblOrder
表中实体的列表。
但现在我想要做这个:DataTable Orders = new DataTable();
Orders.Columns.Add("Order-ID", typeof(int));
Orders.Columns.Add("Order-Name", typeof(string));
Orders.Columns.Add("Order-Items", typeof(string));
dataGridView1.DataSource = Orders;
foreach (tblOrder Order in ListOfOrders)
{
var newRow = Orders.NewRow();
newRow["Order-ID"] = Order.orderID;
newRow["Order-Name"] = Order.orderName;
newRow["Order-Items"] = string.Join(", ", Order.tblItem.Select(item=> item.itemName).ToList());
// System.ObjectDisposedException
(dataGridView1.DataSource as DataTable).Rows.Add(newRow);
}
我无法做到这一点,因为似乎没有存储与外键相关的所有实体在
tblItem
表中的订单。以下是有效的内容:
DataClasses1DataContext DataContext = new DataClasses1DataContext();
ListOfOrders = DataContext.tblOrder.ToList();
DataTable Orders = new DataTable();
Orders.Columns.Add("Order-ID", typeof(int));
Orders.Columns.Add("Order-Name", typeof(string));
Orders.Columns.Add("Order-Items", typeof(string));
dataGridView1.DataSource = Orders;
foreach (tblOrder Order in ListOfOrders)
{
var newRow = Orders.NewRow();
newRow["Order-ID"] = Order.orderID;
newRow["Order-Name"] = Order.orderName;
newRow["Order-Items"] = string.Join(", ", Order.tblItem.Select(item=> item.itemName).ToList());
(dataGridView1.DataSource as DataTable).Rows.Add(newRow);
}
DataContext.Dispose();
但是据我理解,这并不是可取的。
编辑:
我将我的例子扩展到了控制器-视图模式。
using System.Collections.Generic;
using System.Linq;
namespace TestApplication
{
class Controller
{
private List<tblOrder> _orders;
public IList<tblOrder> Orders
{
get
{
return _orders;
}
}
public Controller()
{
using (var DataContext = new DataClasses1DataContext())
{
_orders = DataContext.tblOrder.ToList();
}
}
}
}
现在视图从控制器中检索订单:
using System.Data;
using System.Linq;
using System.Windows.Forms;
namespace TestApplication
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Controller controller = new Controller();
DataTable Orders = new DataTable();
Orders.Columns.Add("Order-ID", typeof(int));
Orders.Columns.Add("Order-Name", typeof(string));
Orders.Columns.Add("Order-Items", typeof(string));
dataGridView1.DataSource = Orders;
foreach (tblOrder Order in controller.Orders)
{
var newRow = Orders.NewRow();
newRow["Order-ID"] = Order.orderID;
newRow["Order-Name"] = Order.orderName;
newRow["Order-Items"] = string.Join(", ", Order.tblItem.Select(item=> item.itemName).ToList());
(dataGridView1.DataSource as DataTable).Rows.Add(newRow);
}
}
}
}
遗憾的是问题仍然存在...
using
块是不可取的。但你可以轻松地解决这个问题。只需放入一个using块即可。 - nvoigt