【发布时间】:2015-11-03 12:24:21
【问题描述】:
重述了我的问题,下面是旧文本
由于我仍然希望得到答案,我想重申我的问题。图片 我有一个带有两个列表的 GUI,一个显示数据库 tblOrders 的所有条目的列表,另一个显示每个订单中的项目。
我可以使用 Linq2sql 或 EF 从数据库中获取所有订单,如下所示:
using (DataClasses1DataContext DataContext = new DataClasses1DataContext())
ListOfOrders = DataContext.tblOrder.ToList();
我可以在列表或datagridview 中显示这些订单。然后选择我想从表tblItems 访问实体集合的作业之一。我可以这样做:
ListOfOrders.First().tblItems.toList();
除非我不能,因为我需要已处理的DataContext。这在某种程度上是有道理的,因为我无法保证没有新项目已添加到该订单中,因为我检索了 ListOfOrders. So ideally I would like to check if there has been an addition to a tblOrder.tblItems 集合,并且仅在需要时才从服务器重新检索该集合。
背景是,我的模型稍微复杂一些:它由 Orders 组成,Orders 由 Parts 组成,而 Parts 又由 Tasks 组成。因此,为了评估每个订单的进度,我必须检索属于订单的所有部分,并且对于每个部分,我必须查看已完成的任务数量。在一个有 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();
但据我了解,这是不可取的。
编辑
我将示例扩展为 Controller-View-Pattern。
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);
}
}
}
}
遗憾的是,问题依旧……
【问题讨论】:
-
手动调用 Dispose 而不是使用
using块是不可取的。但你可以轻松解决这个问题。只需放入 using 块即可。 -
这是正确的并且适用于这个例子,但是如果我有一个控制器处理一个由视图访问的订单列表,那么这就会成为一个问题,视图会显示该列表。
-
你不应该太快地释放上下文,而是你可以将上下文作为表单的实例成员,并在释放表单时释放上下文。
标签: c# sql-server entity-framework linq-to-sql datacontext