為了正确反應測試 EF7 所出現的問題,我同時也用 EF6 進行測試,測試代碼都是一樣的,然後使用 SQL Server Profiler 抓取 EF6、EF7 所生成的 SQL 代碼。
測試環境說明:
EF6 版本:6.1.2-beta1
EF7 版本:7.0.0-beta1
開發環境:VS2015 Preview
SQL Server Profiler 對應版本:SQL Server 2014
四種測試場景(b、c 表示對應關聯實體。):
where b select b
no where select b
where c select b
no where select c
BloggingContext 配置代碼:
OnModelCreating 中的映射配置代碼并沒有對 Blog 和 BlogCate 進行 OneToMany 關聯配置,這樣友善我們使用 Linq 進行 Left Join 文法編寫,EF6 測試項目我使用的是 Model First,因為 EF7 測試項目中的模型更改,在 EF6 測試項目中,隻要一個“Update Model from Database”指令就可以了,這樣友善進行測試,當然項目中建議不要使用 Model First,EF7 的測試項目使用的是 Xunit,EF6 的測試項目直接是控制台應用程式,因為在 VS2015 中,對于非 ASP.NET 5 Class Library 項目,使用 Xunit 暫無法實作測試。下面貼一下,針對 Where Select 不同條件文法實作,EF6、EF7 所出現的具體問題?
測試代碼:
EF6 測試結果:

EF6 生成 SQL 代碼:
EF7 測試結果:
詳細異常資訊:
The multi-part identifier "b.Url" could not be bound. at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource1 completion, Int32 timeout, Task& task, Boolean asyncWrite) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) at System.Data.Common.DbCommand.ExecuteReader() at Microsoft.Data.Entity.Relational.Query.QueryingEnumerable1.Enumerator.MoveNext() at System.Linq.Lookup2.CreateForJoin(IEnumerable1 source, Func2 keySelector, IEqualityComparer1 comparer) at System.Linq.Enumerable.d__6a4.MoveNext() at System.Linq.Enumerable.d__142.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext() at Microsoft.Data.Entity.Query.EntityQueryExecutor.EnumerableExceptionInterceptor1.EnumeratorExceptionInterceptor.MoveNext() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList [TSource] (IEnumerable1 source) at EF7.Tests.EF7_Test.TestWithLeftJoin() in C:\Users\yuezhongxin\Desktop\EF7\src\EF7.Tests\EF7_Test.cs:line 47
EF7 生成 SQL 代碼:
Object reference not set to an instance of an object. Anonymously Hosted DynamicMethods Assembly at lambda_method(Closure , QuerySourceScope ) at System.Linq.Enumerable.ToList[TSource] (IEnumerable1 source) at EF7.Tests.EF7_Test.TestWithLeftJoinExption() in C:\Users\yuezhongxin\Desktop\EF7\src\EF7.Tests\EF7_Test.cs:line 63
總結:
where b select b(EF6 √,EF7 X)
no where select b(EF6 √,EF7 √)
where c select b(EF6 √,EF7 X)
no where select c(EF6 √,EF7 √)
除了這幾種場景,當然還有其他的比如 where b c select b 等等,但都和上面比較類似,這邊就不紀錄了。
本文轉自田園裡的蟋蟀部落格園部落格,原文連結:http://www.cnblogs.com/xishuai/p/ef7-linq-left-join-where-select-error.html,如需轉載請自行聯系原作者