我正在使用Entity Framework中的父表和子表。父表是Invoices,子表是InvoiceLineItems。发票表中的每一行自然代表一张发票。并且,InvoiceLineItems表中的每一行代表发票的一行详细信息(即项目信息,例如项目名称,价格等......)。 InvoiceLineItem表具有Invoice表的外键,因此每个Invoice对象上都有一个InvoiceLineItem集合。
一切都很完美,但我有一个问题。在我们的代码中的某一点,我们构建了一个处于分离状态的Invoice对象列表。然后,我们使用EF数据上下文将所有对象插入数据库(现在它们附加到会话)。然后,我们尝试从此会话中分离Invoice对象,以便我们可以使用新的EF上下文将发票插入另一个数据库。当我们分离发票时,所有InvoiceLineItem集合都是空的。是否有一种方法可以在第一个会话关闭之前分离发票并强制加载行李,以便它们可用于第二个数据上下文?下面是一个代码示例,用于演示我们正在尝试完成的任务。
// Get a list of invoices from Quickbooks
List<Invoice> qbInvoices = GetInvoicesFromQuickbooks(currentThread);
SaveInvoicesToLocalDatabase(dbContextLocal, qbInvoices, currentThread);
// Detach the Invoices from above context so that we can insert them into
// the second database using the new context below.
// NOTE: All Invoice.InvoiceLineItem collections are empty
// How do we force InvoiceLineItems to load???
qbInvoices = dbContextLocal.Invoices.AsNoTracking().ToList();
dbContextLocal.Dispose();
// This only saves rows to Invoices table (i.e. no InvoiceLineItems are saved)
SaveInvoicesToRemoteDatabase(dbContextWeb, qbInvoices, currentThread);
dbContextWeb.Dispose();
答案 0 :(得分:0)
如果我正确理解你,你创建的原始断开的Invoice实体会有子行项目,所以你真的只想解开它们并将它们移动到另一个上下文。我不确定,但AsNoTracking
可能正在进行另一次获取或以其他方式创建您添加的实体的新实例,而不是重用原始实例。
我建议您将DbContext
强制转换为ObjectContext
并在发票上调用Detach
方法,以便将其移至新的上下文。
代替:
qbInvoices = dbContextLocal.Invoices.AsNoTracking().ToList();
dbContextLocal.Dispose();
<强>执行:强>
var objectContext = ((IObjectContextAdapter)context).ObjectContext;
foreach(var invoice in qbInvoices) {
objectContext.Detach(invoice);
}