Restated mia interrogazione, vecchio Testo sottonon possono accedere ai dati correlati dopo lo smaltimento di DataContext in LINQ to SQL
Come sto ancora sperando in una risposta vorrei ribadire la mia domanda. Immagine Ho una GUI con due elenchi, uno che mostra un elenco di tutte le voci di un database tblOrders
e un altro che mostra gli elementi in ciascun ordine.
posso usare Linq2Sql o EF per ottenere tutti gli ordini dal database, in questo modo:
using (DataClasses1DataContext DataContext = new DataClasses1DataContext())
ListOfOrders = DataContext.tblOrder.ToList();
posso visualizzare questi ordine in un elenco o datagridview
. Quindi, su una selezione di uno dei lavori, desidero accedere alla raccolta di entità dalla tabella tblItems
. Posso fare questo in questo modo:
ListOfOrders.First().tblItems.toList();
meno che non possa, perché ho bisogno del DataContext
che sia stata ceduta. Questo ha senso in un modo, dal momento che non posso garantire che non ci siano nuovi elementi che sono stati aggiunti a quell'ordine da quando ho recuperato la collezione ListOfOrders. So ideally I would like to check if there has been an addition to a tblOrder.tblItems
e, se necessario, ho recuperato la nuova raccolta dal server.
Lo sfondo è che il mio modello è un po 'più complesso: consiste in ordini, composti da parti, che consistono in attività. Quindi per valutare lo stato di ogni ordine devo recuperare tutte le parti che appartengono a un ordine e per ognuna di esse devo vedere quante delle attività sono state completate. In un database con 200 lavori, ognuno con 1 a 10 parti, ciò semplifica il mio programma in termini di reattività ...
Qualcuno può aiutarmi?
domanda iniziale
ho trovato un sacco di domande riguardanti DataContext
, ma non ho ancora trovato una soluzione al mio problema. Se faccio la seguente:
using (DataClasses1DataContext DataContext = new DataClasses1DataContext())
ListOfOrders = DataContext.tblOrder.ToList();
Questo mi dà un elenco delle entità nella tabella tblOrder
. ma ora voglio fare questo:
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);
}
E non posso perché l'accesso a tutte le entità nella tblItem
tavolo che sono legati agli ordini di chiave esterna non sembrano essere memorizzati.
Quello che sta lavorando:
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();
ma se ho capito questo non è desiderabile.
EDIT
ho esteso il mio esempio in un 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();
}
}
}
}
E la vista ora recupera gli Ordini dal controller:
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);
}
}
}
}
Purtroppo il problema rimane lo stesso ...
Non è consigliabile chiamare Dispose manualmente anziché utilizzare un blocco 'using'. Ma potresti risolverlo banalmente. Basta inserire un blocco usando. – nvoigt
Questo è corretto e funziona per questo esempio, ma questo diventa un problema se, ad esempio, ho un controller che presenta una lista di ordini a cui si accede da una vista, che visualizza tale lista. – Jonidas
Non si deve disporre il contesto troppo rapidamente, ma è possibile mantenere il contesto come membro di istanza del modulo e disporre del contesto quando il modulo viene eliminato. –