2016-11-14 49 views
0

我有一個Ling Query來計算百分比。使用Linq時的錯誤計算百分比

 var total = db.Schema_Details.Where(x => x.RID == sName).Select(x => new{ 
Rid = x.RID, 
Amount = Convert.ToDouble(x.Lum_Sum_Amount), 
Allocation = Convert.ToDouble(x.Allocation), 
total = ((x.Allocation/100) * x.Lum_Sum_Amount)}).ToList(); 

但發生異常。

enter image description here

我該如何解決這個問題?

+0

從錯誤它聽起來像你變成一個雙變量之一已經在DB –

+0

任何機會之一lum_sum_amount爲空? – BugFinder

+2

我不確定可以在lambda中使用Concert.ToDouble。它通過ef解析成sql。您可以嘗試使用ToList獲取列表在where調用之後(將執行sql),然後在列表中使用select方法。讓我知道它是否有效 –

回答

2

由於您使用標識符db,我假設db是一個DbContext。這意味着您的linq語句將在數據庫服務器端的SQL中執行,而不是在您的內存中執行(SQL或類似的,取決於您正在使用的DB的類型)。

如果您在調試器中檢查語句的類型,您可以看到以下內容:它是IQueryable還是IEnumerable? IQueryables由數據庫服務器執行,IEnumerable通常在您的內存中執行。通常你的數據庫服務器可以比你更快,更高效地執行你的linq語句,所以最好確保你的linq語句是IQueryable。

然而,缺點是,你的數據庫服務器不知道你的任何類,函數或.NET。所以在IQueryables中,你只能使用相當簡單的計算。

如果你真的需要中途某處調用一些本地函數的聲明LINQ,添加AsEnumerable()到您的語句:

var myLinqResult = db. ...  // something IQueryable 
    .Where(item => ...)  // simple statement: still IQueryable 
    .Select(item => ...)  // still simple, still IQueryable 
    // now you want to call one of your own functions: 
    .AsEnumerable() 
    .Select(item => myOwnLocalFunctions(item)); 

stackoverflow: Difference between IQueryable and IEnumerable

要執行的本地函數是Convert.ToDouble。 IQueryable不知道Convert類,因此不能像IQueryable那樣執行你的函數。 AsEnumerable將解決這個問題。

但是,在這種情況下,我不會建議使用AsEnumerable。在數據庫上執行linq語句時,儘量避免使用本地類和函數調用。而不是Convert.ToDouble使用(double)x.Sum_Amount。您的linq-to-sql轉換器(或類似的數據庫語言轉換器)將知道如何將其轉換爲IQueryable。

有一些計算其中有SQL等效項,如DateTime計算或字符串反轉。如果您必須在本地內存中執行諸如DateTime.AddDays(1)之類的操作,並且存在完美的SQL等效項,那將是一件恥辱。如果您需要在您的本地功能之後加入,選擇或GroupBy,這尤其會成爲問題。您的數據庫服務器可以比您更有效地完成這些任務。幸運的是,它們有一些IQueryable擴展功能。他們可以在System.Data.Entity.DbFunctions