我一直在擺弄整整兩天,現在有一個簡單的問題。IQueryable的擴展沒有轉換到SQL
我有一個產品實體和ProductLocationHistory實體的數據庫。 ProductLocationHistory具有對倉庫,聯繫人或關係的引用。每次產品移動時,都會得到一個新條目,以便跟蹤產品的過去。因此,當前位置是由ProductLocationHistory的DateCreation字段確定的最後一個條目。
一個例子:
var storehousesWithBorrowedItems = productService.GetAllProducts()
.Select(p => p.ProductLocationHistories
.SingleOrDefault(plh => plh.DateCreation == p.ProductLocationHistories.Max(grp => grp.DateCreation)))
.Select(plh => plh.Storehouse)
.Distinct();
這些是目前有一個產品的所有倉庫。
當然,我需要確定產品的當前位置時,將代碼編寫出來非常不方便。由於可能出現的一致性問題,我認爲對產品中當前的ProductLocationHistory的引用完全是不受歡迎的。我喜歡這樣的:
Product.ProductLocationHistories.Current();
所以,我想:
public static ProductLocationHistory Current(this EntitySet<ProductLocationHistory> plhs)
{
return plhs.SingleOrDefault(plh => plh.DateCreation == plhs.Max(grp => grp.DateCreation));
}
這並不在可查詢的工作,我得到一個「當前沒有支持轉換爲SQL」,由於產品組合而ProductLocationHistory通常是查詢的「開始」,我希望保留IQueryable而不是立即對IEnumerable進行查詢,併爲每個產品查詢以確定當前位置!更別說以後還有其他什麼東西......任何實體的當前日誌條目經常被使用,只要它能夠工作並保持可查詢,.Current()函數的複雜程度就不重要了。我希望我的.Current(...)函數可以工作,因爲底層代碼是可查詢的,但我仍然遇到異常。當代碼與第一個示例中一樣內聯時,我沒有得到異常。
我已經經歷過像Func,ProductLocationHistory >>和表達式< ...>的可能性...>,但是我找不到我正在尋找的示例。類型Product.CurrentProductLocationHistory()的解決方案可能會更好。絕對最好的解決辦法是更通用的形式:
Current<T> (IQueryable<T> collection, string field) { return entity with max field of collection }
幫助將不勝感激,我一直在嘗試這個很長一段時間,我敢肯定那一定是可能的,因爲內部功能LINQ本身 - 任何,首先,計數,最大 - 如果需要也可以保持查詢。
更新
目前,以下工作:
Expression<Func<Product, ProductLocationHistory>> expression = IQueryable.Current(null);
var ken = productService.GetAllProducts()
.Where(p => p.OnLoan)
.Select(expression)
.Where(plh => plh.Storehouse != null)
.Select(plh => plh.Storehouse)
.Distinct();
public static Expression<Func<Product, ProductLocationHistory>> Current(this EntitySet<ProductLocationHistory> productLocationHistories)
{
Expression<Func<Product, ProductLocationHistory>> expression = p => p.ProductLocationHistories
.SingleOrDefault(plh => plh.DateCreation == p.ProductLocationHistories.Max(plhs => plhs.DateCreation));
return expression;
}
朝着正確方向邁出的一步,但我還沒有完全滿意。我希望能夠使用p.ProductLocationHistories()。Current()來繼續我的追求。
感謝Kirill!這是我第一次將C#代碼翻譯成SQL!朝着正確的方向邁出了一步!
有了這個擴展方法,你可以* *調用.Current()如果我不是誤。你可以展示你想使用的調用約定的示例嗎?此外,使用'OrderByDescending(pld => pld.DateCreation).FirstOrDefault()'比使用'SingleOrDefault'查詢max要快很多。 – jessehouwing
我會盡快升級到ASP.NET 4.5,然後嘗試解決方案[link](http://stackoverflow.com/questions/10826275/queryable-extension-method-for-linq2entities)。目前我們正在收購Visual Studio 2012.之後我可能會更新此問題。 – Paul1977