我正在尋找一個使用單個SELECT來獲取整個LINQ對象層次結構的特定問題的答案。如何使用單個LINQ查詢將所有父對象選擇到DataContext中?
起初我試圖用LoadOptions填充儘可能多的LINQ對象,但是AFAIK這個方法只允許使用LoadWith在一個查詢中鏈接單個表。因此,我發明了一個解決方案,強制設置實體的所有父對象哪一個列表將被提取,儘管存在多個SELECTS進入數據庫的問題 - 單個查詢導致兩個SELECTS在相同的LINQ環境中具有相同的參數。
對於這個問題我已經簡化了此查詢到流行的發票例如:
public static class Extensions
{
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> collection, Action<T> func)
{
foreach(var c in collection)
{
func(c);
}
return collection;
}
}
public IEnumerable<Entry> GetResults(AppDataContext context, int CustomerId)
{
return
(
from entry in context.Entries
join invoice in context.Invoices on entry.EntryInvoiceId equals invoice.InvoiceId
join period in context.Periods on invoice.InvoicePeriodId equals period.PeriodId
// LEFT OUTER JOIN, store is not mandatory
join store in context.Stores on entry.EntryStoreId equals store.StoreId into condStore
from store in condStore.DefaultIfEmpty()
where
(invoice.InvoiceCustomerId = CustomerId)
orderby entry.EntryPrice descending
select new
{
Entry = entry,
Invoice = invoice,
Period = period,
Store = store
}
).ForEach(x =>
{
x.Entry.Invoice = Invoice;
x.Invoice.Period = Period;
x.Entry.Store = Store;
}
).Select(x => x.Entry);
}
在調用此函數,並通過結果集穿越,例如:
var entries = GetResults(this.Context);
int withoutStore = 0;
foreach(var k in entries)
{
if(k.EntryStoreId == null)
withoutStore++;
}
結果查詢數據庫的外觀喜歡(單個結果取自):
SELECT
[t0].[EntryId],
[t0].[EntryInvoiceId],
[t0].[EntryStoreId],
[t0].[EntryProductId],
[t0].[EntryQuantity],
[t0].[EntryPrice],
[t1].[InvoiceId],
[t1].[InvoiceCustomerId],
[t1].[InvoiceDate],
[t1].[InvoicePeriodId],
[t2].[PeriodId],
[t2].[PeriodName],
[t2].[PeriodDateFrom],
[t4].[StoreId],
[t4].[StoreName]
FROM
[Entry] AS [t0]
INNER JOIN [Invoice] AS [t1] ON [t0].[EntryInvoiceId] = [t1].[InvoiceId]
INNER JOIN [Period] AS [t2] ON [t2].[PeriodId] = [t1].[InvoicePeriodId]
LEFT OUTER JOIN (
SELECT 1 AS [test], [t3].[StoreId], [t3].[StoreName]
FROM [Store] AS [t3]
) AS [t4] ON [t4].[StoreId] = ([t0].[EntryStoreId])
WHERE (([t1].[InvoiceCustomerId]) = @p0)
ORDER BY [t0].[InvoicePrice] DESC
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [186]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1
SELECT
[t0].[EntryId],
[t0].[EntryInvoiceId],
[t0].[EntryStoreId],
[t0].[EntryProductId],
[t0].[EntryQuantity],
[t0].[EntryPrice],
[t1].[InvoiceId],
[t1].[InvoiceCustomerId],
[t1].[InvoiceDate],
[t1].[InvoicePeriodId],
[t2].[PeriodId],
[t2].[PeriodName],
[t2].[PeriodDateFrom],
[t4].[StoreId],
[t4].[StoreName]
FROM
[Entry] AS [t0]
INNER JOIN [Invoice] AS [t1] ON [t0].[EntryInvoiceId] = [t1].[InvoiceId]
INNER JOIN [Period] AS [t2] ON [t2].[PeriodId] = [t1].[InvoicePeriodId]
LEFT OUTER JOIN (
SELECT 1 AS [test], [t3].[StoreId], [t3].[StoreName]
FROM [Store] AS [t3]
) AS [t4] ON [t4].[StoreId] = ([t0].[EntryStoreId])
WHERE (([t1].[InvoiceCustomerId]) = @p0)
ORDER BY [t0].[InvoicePrice] DESC
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [186]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1
問題是爲什麼有兩個查詢,我怎樣才能沒有這樣的黑客獲取LINQ對象?
肯定LoadWith的作品 - 我不能重複爲什麼我以前的嘗試使用多個LoadWith失敗,謝謝你救了我不必要的遊蕩。 – too
對於記錄 - 對於LoadWith正常工作,查詢必須包含所有需要提取的表,即使它們是由上下文的LoadOptions中的LoadWith指令指定的,它也不會自動地加入所有父表。 – too