2017-06-15 55 views
1

(很抱歉的模糊標題,真的不知道該怎麼做了。)獲取最新的兩個項目,用於兩個給定日期與EF 6

這是.NET 4.7,EF 6.1。我有兩個表格:一組產品和一組歷史價格。我需要編寫一些代碼,以獲取所提供的兩個日期(開始和結束)中所有產品及其價格的列表。這本質上是一個報告,看看這兩個日期之間產品價格是如何變化的,但我只需要開始/結束價格,而不是兩者之間的所有東西。

我能想到的唯一方法就像下面的代碼。我會運行兩次 - 一次是開始日期,一次是結束日期 - 然後我會將這兩個列表加入我需要的模型類型的一個列表中。我不能爲我的生活弄清楚如何做到這一點。 我應該怎麼做到這一點?

簡表的佈局:

Product  HistoricalPrice 
-------  --------------- 
-Id   -Id 
-Name   -ProductId 
       -ModifiedAt 
       -NewPrice 

這是我嘗試使用的代碼。 Product是對HistoricalPriceProduct的引用,它是該類的一部分,並且以ProductId字段引用。我需要從此代碼的最終結果中獲取產品名稱/ ID。

var historicalStartPrices = await _context.ProductHistoricalPrices 

    // need to include the product itself 
    .Include(p => p.Product) 

    // only get prices that come before the start date 
    .Where(p => p.ModifiedAt <= start) 

    // order from most recent -> oldest by modified date 
    .OrderByDescending(p => p.ModifiedAt) 

    // group prices by the product ID 
    .GroupBy(p => p.ProductId) 

    // take only the first result for each product ID 
    .Select(g => g.First()) 

    // enumerate the results 
    .ToListAsync(); 

即代碼拋出該異常:

NotSupportedException異常:該方法「第一」只能用作最終查詢操作。請考慮在此實例中使用方法「FirstOrDefault」。

如果我切換到FirstOrDefault,那麼所有Product都爲空。

回答

0

爲什麼你需要包括產品到產品的歷史價格?這不是相關的嗎? 也許你的代碼的簡單修改,將有助於你的目標:

var historicalStartPrices = await _context.ProductHistoricalPrices; 

// only get prices that come between start and end dates 
.Where(p => p.ModifiedAt >= start && p.ModifiedAt <= end 

// order from most recent -> oldest by modified date 
.OrderByDescending(p => p.ModifiedAt) 

// take only prices foreach products in ProductHistoricalPrices 
.Select(g => g.NewPrice) 

// enumerate the results 
.ToListAsync(); 
+0

我剛剛添加了這個問題,抱歉的混淆。 'Product'是對'HistoricalPrice'的'Product'的引用,它是類的一部分,並且用'ProductId'字段引用。我需要從此代碼的最終結果中獲取產品名稱/ ID。 – vaindil

0

這可能是在你的代碼的其他地方引用,但什麼是p.Product指?我沒有在您的表格中看到類似的通用字段。

此外,如果您試圖將第一個結果輸入到需要查詢的字段旁邊。

假設第一個查詢是沒有必要的,您的查詢可能看起來否則相同:

.Where(p => p.ModifiedAt <= start) 
.OrderByDescending(p => p.ModifiedAt) 
.GroupBy(p => p.ProductId.First()) 
.ToListAsync(); 

如果你真的需要從其它表引用一個項目,你既可以認爲值存儲在一個變量或者你可以簡單地檢索您最新的條目:`query.Where(p => p.ModifiedAt

+0

我剛剛添加了這個問題,抱歉的混淆。 'Product'是對'HistoricalPrice'的'Product'的引用,它是類的一部分,並且用'ProductId'字段引用。我需要從此代碼的最終結果中獲取產品名稱/ ID。 – vaindil

0

解決你的問題(每個產品中顯示的時間範圍最初和最終的價格)是你有您的Linq查詢如下所示:

var historicalPrices = await _context.ProductHistoricalPrices.Where(x => x.ModifiedAt >= startDate && x.ModifiedAt <= endDate).Select(x => new 
    { 
    ProductId = x.ProductId, 
    ProductName = x.Product.Name, 
    Price = x.NewPrice, 
    ModificationDate = x.ModifiedAt 
    }).GroupBy(x => x.ProductId).Select(x => new 
{ 
    ProductName = x.FirstOrDefault().ProductName, 
    InitialPrice = x.OrderBy(x => x.ModificationDate).FirstOrDefault().Price, 
    FinalPrice = x.OrderByDescending(x => x.ModificationDate).FirstOrDefault().Price 
}).ToListAsync();