Linq中欄位資料型別轉換問題(Linq to entity,LINQ to Entities 不識別方法"System.String ToString()"問題解決)
1、在工作中碰到這樣一個問題:
使用linq時,需要查詢兩個表,在這兩張表中關聯欄位分別是int,和varchar()也就是string,在linq中對這兩個欄位進行關聯,
如果強制型別轉換兩個不同型別的欄位,就會報響應的擴充套件方法無法自動推斷引數型別的問題(比如:我用的是groupjoin擴充套件方法),
如果進行了常規的型別轉換,比如將int欄位對應的轉換為string(ToString方法),這時編譯的時候不會有問題了。
但是在執行的時候會報如下錯誤:
LINQ to Entities 不識別方法"System.String ToString()",因此該方法無法轉換為儲存表示式.
2、解決方法:
使用System.Data.Objects.SqlClient.SqlFunctions.StringConvert()對相應的欄位進行轉換,結果可以了。
比如:
我有問題的Linq是下面這個:
var borrowLeftOutJoinLog =
query.GroupJoin(
groupRtnToolByID,
c => c.ID.ToString(),
d => d.BizID, (g, f) => new { Item = g, Detail = f })
.SelectMany(detail => detail.Detail.DefaultIfEmpty(), (a, b) => new { a.Item, RtnSum = (decimal?)b.RtnSum })
.Where(a => (a.RtnSum ?? 0) < a.Item.TBor_Qty)
.Select(a => a.Item);
注意:上面的ID和BizID是有關聯的,但是在兩個表中分別被設計成了int,string,所以這裡對ID進行了ToString的轉換,結果出現了上面提示的錯誤。
運用解決方法後的語句如下:
var borrowLeftOutJoinLog =
query.GroupJoin(
groupRtnToolByID,
c => System.Data.Objects.SqlClient.SqlFunctions.StringConvert((double)c.ID),
d => d.BizID
.SelectMany(detail => detail.Detail.DefaultIfEmpty(), (a, b) => new { a.Item, RtnSum = (decimal?)b.RtnSum })
.Where(a => (a.RtnSum ?? 0) < a.Item.TBor_Qty)
.Select(a => a.Item);
3、後感:
遇到這個問題後,自己嘗試瞭解決,可是都行不通,於是轉而求助網路(感謝這個時代吧!!!),
也看到了幾篇關於這個的解決方法,其中就包括ToString方法,而且還言之鑿鑿,再不就是說一些框架,底層問題,
難道我為了這個芝麻大點的事,也要去自己重寫,去實現很多內容嗎??
如果是,只能說我選錯了技術,它還不成熟。
可是,結果不是這樣的,Linq出來已經很久了,它包含的內容也是很多,不應該是這樣的,所以我繼續找
在這裡我找到了:
這句介紹了問題的原因:StingyJack, the problem is with the ELINQ (linq 2 entities), because it translates your code to SQL, and when it comes to an inner ToString request, it doesn't know how to translate 'ToString' to SQL. Unlike with linq 2 objects, when there is no translation, and everything is CLR lambdas, then it's performed directly on the requested objects;
下面這個給了具體的解決方法:
With EF v4 you can useSqlFunctions.StringConvert. There is no overload for int so you need to cast to a double or a decimal. Your code ends up looking like this:
|
|||||||||||||||
|
所以,我覺得回答別人問題時要慎重,要針對別人給出的條件自己去試驗,不能簡單憑經驗,不能說空話,更不能想當然。
給出結果要直接(當然如果要是一語中的,切中要害,那當然不用直接給出,可是我沒有這樣的功力,起碼在linq上沒有)。