如果不想延遲載入,可以通過設置:context.Configuration.LazyLoadingEnabled = false;或查詢時加上AsNoTracking()方法即可。如果不想生成代理,可以通過設置:context.Configuration.ProxyCreationEnabled =...
如果不想延遲載入,可以通過設置:context.Configuration.LazyLoadingEnabled = false;或查詢時加上AsNoTracking()方法即可。
如果不想生成代理,可以通過設置:context.Configuration.ProxyCreationEnabled = false;
註意當context.Configuration.ProxyCreationEnabled = false;時延遲載入也就不生效,原理很簡單,因為沒有代理。
當禁用延遲載入後,關聯屬性(導航屬性)不會被實例化,這時如果需要實例化該屬性,則需要通過Include方法,意為顯式載入(也有人稱為饑餓載入),具體的用法也可參見我之前的文章:http://www.cnblogs.com/zuowj/p/4514230.html
好了有了上面知識的瞭解,我們想實現一次性載入所有內容包含關聯屬性的值,且不要生成代理對象,就很簡單了,我項目中的語句如下:
var context = new LocalDbEntities(); context.Configuration.LazyLoadingEnabled = false; context.Configuration.ProxyCreationEnabled = false; result=context.Set<TA_CWTransferRequestInfo>().Where(t => true).Include(t => t.TA_CWBankAccountInfo).GroupBy(t => t.TA_CWBankAccountInfo.bkcode) .ToDictionary(gp => gp.Key, gp => gp.ToList());
代碼簡單說明一下,TA_CWTransferRequestInfo有一個關聯屬性TA_CWBankAccountInfo,我想實現依據TA_CWBankAccountInfo.bkcode來分組並存入Dictionary中,最後我需要用到TA_CWTransferRequestInfo.TA_CWBankAccountInfo屬性的信息,原本以為沒有問題,但實際使用時,卻報錯:無法對 null 引用執行運行時綁定,經DEBUG時發現TA_CWTransferRequestInfo.TA_CWBankAccountInfo=null,這就有點不解了,明明我使用了Include,為何沒有載入呢?不解之餘查看了一下上述LINQ生成的SQL語句如下:
SELECT [Project2].[C1] AS [C1], [Project2].[bkcode] AS [bkcode], [Project2].[C2] AS [C2], [Project2].[id] AS [id], [Project2].[fromactacn] AS [fromactacn], [Project2].[toactacn] AS [toactacn], [Project2].[toibkn] AS [toibkn], [Project2].[toname] AS [toname], [Project2].[toaddr] AS [toaddr], [Project2].[tobknm] AS [tobknm], [Project2].[tobkcode] AS [tobkcode], [Project2].[trnamt] AS [trnamt], [Project2].[trncur] AS [trncur], [Project2].[priolv] AS [priolv], [Project2].[furinfo] AS [furinfo], [Project2].[trfdate] AS [trfdate], [Project2].[trftime] AS [trftime], [Project2].[comacn] AS [comacn], [Project2].[field1] AS [field1], [Project2].[field2] AS [field2], [Project2].[field3] AS [field3], [Project2].[field4] AS [field4], [Project2].[field5] AS [field5], [Project2].[field6] AS [field6], [Project2].[field7] AS [field7], [Project2].[field8] AS [field8], [Project2].[processing] AS [processing], [Project2].[transtype] AS [transtype], [Project2].[trfmode] AS [trfmode], [Project2].[createdt] AS [createdt], [Project2].[lastupdatedt] AS [lastupdatedt], [Project2].[lastrspid] AS [lastrspid], [Project2].[rowversion] AS [rowversion], [Project2].[lyd_guid] AS [lyd_guid] FROM ( SELECT [Distinct1].[bkcode] AS [bkcode], 1 AS [C1], [Join2].[id] AS [id], [Join2].[fromactacn] AS [fromactacn], [Join2].[toactacn] AS [toactacn], [Join2].[toibkn] AS [toibkn], [Join2].[toname] AS [toname], [Join2].[toaddr] AS [toaddr], [Join2].[tobknm] AS [tobknm], [Join2].[tobkcode] AS [tobkcode], [Join2].[trnamt] AS [trnamt], [Join2].[trncur1] AS [trncur], [Join2].[priolv] AS [priolv], [Join2].[furinfo] AS [furinfo], [Join2].[trfdate] AS [trfdate], [Join2].[trftime] AS [trftime], [Join2].[comacn] AS [comacn], [Join2].[field11] AS [field1], [Join2].[field21] AS [field2], [Join2].[field31] AS [field3], [Join2].[field41] AS [field4], [Join2].[field51] AS [field5], [Join2].[field6] AS [field6], [Join2].[field7] AS [field7], [Join2].[field8] AS [field8], [Join2].[processing] AS [processing], [Join2].[transtype] AS [transtype], [Join2].[trfmode] AS [trfmode], [Join2].[createdt] AS [createdt], [Join2].[lastupdatedt1] AS [lastupdatedt], [Join2].[lastrspid] AS [lastrspid], [Join2].[rowversion1] AS [rowversion], [Join2].[lyd_guid] AS [lyd_guid], CASE WHEN ([Join2].[priolv] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2] FROM (SELECT DISTINCT [Extent2].[bkcode] AS [bkcode] FROM [dbo].[TA_CWTransferRequestInfo] AS [Extent1] INNER JOIN [dbo].[TA_CWBankAccountInfo] AS [Extent2] ON [Extent1].[fromactacn] = [Extent2].[actacn] ) AS [Distinct1] LEFT OUTER JOIN (SELECT [Extent3].[id] AS [id], [Extent3].[fromactacn] AS [fromactacn], [Extent3].[toactacn] AS [toactacn], [Extent3].[toibkn] AS [toibkn], [Extent3].[toname] AS [toname], [Extent3].[toaddr] AS [toaddr], [Extent3].[tobknm] AS [tobknm], [Extent3].[tobkcode] AS [tobkcode], [Extent3].[trnamt] AS [trnamt], [Extent3].[trncur] AS [trncur1], [Extent3].[priolv] AS [priolv], [Extent3].[furinfo] AS [furinfo], [Extent3].[trfdate] AS [trfdate], [Extent3].[trftime] AS [trftime], [Extent3].[comacn] AS [comacn], [Extent3].[field1] AS [field11], [Extent3].[field2] AS [field21], [Extent3].[field3] AS [field31], [Extent3].[field4] AS [field41], [Extent3].[field5] AS [field51], [Extent3].[field6] AS [field6], [Extent3].[field7] AS [field7], [Extent3].[field8] AS [field8], [Extent3].[processing] AS [processing], [Extent3].[transtype] AS [transtype], [Extent3].[trfmode] AS [trfmode], [Extent3].[createdt] AS [createdt], [Extent3].[lastupdatedt] AS [lastupdatedt1], [Extent3].[lastrspid] AS [lastrspid], [Extent3].[rowversion] AS [rowversion1], [Extent3].[lyd_guid] AS [lyd_guid], [Extent4].[bkcode] AS [bkcode] FROM [dbo].[TA_CWTransferRequestInfo] AS [Extent3] INNER JOIN [dbo].[TA_CWBankAccountInfo] AS [Extent4] ON [Extent3].[fromactacn] = [Extent4].[actacn] ) AS [Join2] ON ([Distinct1].[bkcode] = [Join2].[bkcode]) OR (1 = 0) ) AS [Project2] ORDER BY [Project2].[bkcode] ASC, [Project2].[C2] ASC
看到這個SQL語句我也是醉了,與我的本意完全不同,從上面的SQL語句可以看出來:它雖然關聯時有用到[TA_CWBankAccountInfo],但最後只查出[TA_CWTransferRequestInfo]的欄位,當然也就無法實例化關聯的TA_CWBankAccountInfo屬性了,最後得出結論,當使用GroupBy+ToDictionary時,Include方法無效。
鑒於上述結論,我將上述語句稍微作了一下調整,就成功通過測試了,更改後的語句:
var context = new LocalDbEntities(); context.Configuration.LazyLoadingEnabled = false; context.Configuration.ProxyCreationEnabled = false; return context.Set<TA_CWTransferRequestInfo>().Where(t => true).Include(t => t.TA_CWBankAccountInfo).ToList().GroupBy(t => t.TA_CWBankAccountInfo.bkcode) .ToDictionary(gp => gp.Key, gp => gp.ToList());
發現區別了沒有?我只是在Include後加了一個ToList()方法就可以了,目的是先從資料庫查詢出符合條件的數據(包含關聯的數據),然後再在本地進行GroupBy操作,可以看一下生成的SQL語句:
SELECT [Extent1].[priolv] AS [priolv], [Extent1].[id] AS [id], [Extent1].[fromactacn] AS [fromactacn], [Extent1].[toactacn] AS [toactacn], [Extent1].[toibkn] AS [toibkn], [Extent1].[toname] AS [toname], [Extent1].[toaddr] AS [toaddr], [Extent1].[tobknm] AS [tobknm], [Extent1].[tobkcode] AS [tobkcode], [Extent1].[trnamt] AS [trnamt], [Extent1].[trncur] AS [trncur], [Extent1].[furinfo] AS [furinfo], [Extent1].[trfdate] AS [trfdate], [Extent1].[trftime] AS [trftime], [Extent1].[comacn] AS [comacn], [Extent1].[field1] AS [field1], [Extent1].[field2] AS [field2], [Extent1].[field3] AS [field3], [Extent1].[field4] AS [field4], [Extent1].[field5] AS [field5], [Extent1].[field6] AS [field6], [Extent1].[field7] AS [field7], [Extent1].[field8] AS [field8], [Extent1].[processing] AS [processing], [Extent1].[transtype] AS [transtype], [Extent1].[trfmode] AS [trfmode], [Extent1].[createdt] AS [createdt], [Extent1].[lastupdatedt] AS [lastupdatedt], [Extent1].[lastrspid] AS [lastrspid], [Extent1].[rowversion] AS [rowversion], [Extent1].[lyd_guid] AS [lyd_guid], [Extent2].[actacn] AS [actacn], [Extent2].[ibknum] AS [ibknum], [Extent2].[actnam] AS [actnam], [Extent2].[bknm] AS [bknm], [Extent2].[bkcode] AS [bkcode], [Extent2].[addr] AS [addr], [Extent2].[actacnas] AS [actacnas], [Extent2].[trncur] AS [trncur1], [Extent2].[field1] AS [field11], [Extent2].[field2] AS [field21], [Extent2].[field3] AS [field31], [Extent2].[field4] AS [field41], [Extent2].[field5] AS [field51], [Extent2].[lastupdatedt] AS [lastupdatedt1], [Extent2].[rowversion] AS [rowversion1] FROM [dbo].[TA_CWTransferRequestInfo] AS [Extent1] INNER JOIN [dbo].[TA_CWBankAccountInfo] AS [Extent2] ON [Extent1].[fromactacn] = [Extent2].[actacn]
這個SQL語句是既簡潔又明瞭,符合我的意圖,從遇到的這個坑得到啟示,有時不要把問題複雜化,換個角度看問題或許能找到更好的解決辦法。