EntityFramework 7 Left Join Where Select 奇怪问题
这篇博文纪录一下:使用 EF7,当 Linq 查询中使用 "Left Join" 语法(DefaultIfEmpty),Where Select 不同条件语法实现,出现的不同问题。
为了正确反应测试 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 配置代码:
using Microsoft.Data.Entity;
using Microsoft.Data.Entity.Metadata;
using System.Collections.Generic;
namespace EF7
{
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<BlogCate> BlogCates { get; set; }
protected override void OnConfiguring(DbContextOptions builder)
{
builder.UseSqlServer(@"Server=.;Database=Blogging;Trusted_Connection=True;");
}
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Blog>()
.Key(b => b.BlogId);
builder.Entity<BlogCate>()
.Key(b => b.CateId);
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public int BlogCateId { get; set; }
}
public class BlogCate
{
public int CateId { get; set; }
public string CateName { get; set; }
}
}
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 所出现的具体问题?
1. where b select b
测试代码:
[Fact]
public void TestWithLeftJoin()
{
using (var context = new BloggingContext())
{
var query = from b in context.Blogs
join c in context.BlogCates on b.BlogCateId equals c.CateId into left
from c in left.DefaultIfEmpty()
where b.Url == "http://www.cnblogs.com/"
select b.BlogId;
var result = query.ToList();
}
}
EF6 测试结果:

EF6 生成 SQL 代码:
SELECT
[Extent1].[BlogId] AS [BlogId]
FROM [dbo].[Blog] AS [Extent1]
LEFT OUTER JOIN [dbo].[BlogCate] AS [Extent2] ON [Extent1].[BlogCateId] = [Extent2].[CateId]
WHERE N'http://www.cnblogs.com/' = [Extent1].[Url]
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
2. no where select b
测试代码:
[Fact]
public void TestWithLeftJoin()
{
using (var context = new BloggingContext())
{
var query = from b in context.Blogs
join c in context.BlogCates on b.BlogCateId equals c.CateId into left
from c in left.DefaultIfEmpty()
select b.BlogId;
var result = query.ToList();
}
}
EF6 测试结果:

EF6 生成 SQL 代码:
SELECT
[Extent1].[BlogId] AS [BlogId]
FROM [dbo].[Blog] AS [Extent1]
LEFT OUTER JOIN [dbo].[BlogCate] AS [Extent2] ON [Extent1].[BlogCateId] = [Extent2].[CateId]
EF7 测试结果:

EF7 生成 SQL 代码:
SELECT [b].[BlogCateId], [b].[BlogId]
FROM [Blog] AS [b]
3. where c select b
测试代码:
[Fact]
public void TestWithLeftJoin()
{
using (var context = new BloggingContext())
{
var query = from b in context.Blogs
join c in context.BlogCates on b.BlogCateId equals c.CateId into left
from c in left.DefaultIfEmpty()
where c.CateName == "EF7"
select b.BlogId;
var result = query.ToList();
}
}
EF6 测试结果:

EF6 生成 SQL 代码:
SELECT
[Extent1].[BlogId] AS [BlogId]
FROM [dbo].[Blog] AS [Extent1]
INNER JOIN [dbo].[BlogCate] AS [Extent2] ON [Extent1].[BlogCateId] = [Extent2].[CateId]
WHERE N'EF7' = [Extent2].[CateName]
EF7 测试结果:

详细异常信息:
Object reference not set to an instance of an object.
Anonymously Hosted DynamicMethods Assembly
at lambda_method(Closure , QuerySourceScope )
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.TestWithLeftJoinExption() in C:\Users\yuezhongxin\Desktop\EF7\src\EF7.Tests\EF7_Test.cs:line 63
4. no where select c
测试代码:
[Fact]
public void TestWithLeftJoin()
{
using (var context = new BloggingContext())
{
var query = from b in context.Blogs
join c in context.BlogCates on b.BlogCateId equals c.CateId into left
from c in left.DefaultIfEmpty()
select c;
var result = query.ToList();
}
}
EF6 测试结果:

EF6 生成 SQL 代码:
SELECT
[Extent2].[CateId] AS [CateId],
[Extent2].[CateName] AS [CateName]
FROM [dbo].[Blog] AS [Extent1]
LEFT OUTER JOIN [dbo].[BlogCate] AS [Extent2] ON [Extent1].[BlogCateId] = [Extent2].[CateId]
EF7 测试结果:

EF7 生成 SQL 代码:
SELECT [c].[CateId], [c].[CateName]
FROM [BlogCate] AS [c]
SELECT [b].[BlogCateId]
FROM [Blog] AS [b]
总结:
- 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 等等,但都和上面比较类似,这边就不纪录了。
已提交至 EntityFramework 7 issues:Use EF7, Linq Left Join Where Select is error.
EntityFramework 7 Left Join Where Select 奇怪问题的更多相关文章
- EntityFramework 7 Left Join Where is error(Test record)
First of all, my English is very poor, so I may not be a very good expression, very sorry! In this b ...
- EntityFramework 7 Join Count LongCount 奇怪问题
先吐槽一下,EF7 目前来说,真对的起现在的版本命名:"EntityFramework": "7.0.0-beta1". 这篇博文纪录一下:当 Linq 查询中 ...
- EntityFramework 7 Join Count LongCount 奇怪问题(已修复)
问题说明: 博客问题纪录 Use EF7, Linq Join Count is error EF7 Code Commit EF7 版本(注意 rc): 旧版本:"EntityFramew ...
- 成功的拆开了SELECT里JOIN个SELECT是啥
SELECT * FROM table JOIN table ON a=b ----------------------- JOIN (SELECT* FROM table JOIN table ON ...
- JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-006Mixing inheritance strategies(@SecondaryTable、@PrimaryKeyJoinColumn、<join fetch="select">)
一.结构 For example, you can map a class hierarchy to a single table, but, for a particular subclass, s ...
- 爱与恨的抉择:ASP.NET 5+EntityFramework 7
EF7 的纠缠 ASP.NET 5 的无助 忘不了你的好 一开始列出的这个博文大纲,让我想到了很久之前的一篇博文:恋爱虽易,相处不易:当EntityFramework爱上AutoMapper,只不过这 ...
- ASP.NET 5+EntityFramework 7
爱与恨的抉择:ASP.NET 5+EntityFramework 7 EF7 的纠缠 ASP.NET 5 的无助 忘不了你的好 一开始列出的这个博文大纲,让我想到了很久之前的一篇博文:恋爱虽易,相 ...
- 对于SQL的Join,在学习起来可能是比较乱的。我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚。Coding Horror上有一篇文章,通过文氏图 Venn diagrams 解释了SQL的Join。我觉得清楚易懂,转过来。
对于SQL的Join,在学习起来可能是比较乱的.我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚.Codi ...
- MySQL SELECT语法(三)JOIN语法详解
源自MySQL 5.7 官方手册:13.2.9.2 JOIN Syntax SELECT select_expr From table_references JOIN... WHERE... 如上所示 ...
随机推荐
- nodejs的实现原理和搭建服务器(动态)
心得体会 今天是我学习的Node.js的第二天,所谓的node.js其实它是javascript编写的服务器的语言,同时它又是属于后台的框架,是一个开放性的平台. 一.相关理论知识: 我们可以用 ...
- Cannot run gnome extension in browser
Error Message: We cannot detect a running copy of GNOME on this system, so some parts of the interfa ...
- tabhost 下 setOnItemClickListener失效的问题
分析了一下代码,应该是tabhost 的ontabchangedListener接管了下面应该由setOnItemClickListener接管的部分,导致不能相应setOnItemClickList ...
- ArcGIS AddIN开发:如何调用ArcMap中的选择工作空间的窗体
示例代码如下: public static IWorkspaceName BrowseWorkspace(int hwnd,out IWorkspace ws) { IGxObjectFilterCo ...
- Dexpress 中 grid的使用
grid 中加入checkbox Run desiger Columns ColumnEdit中选择checkbox 此时我们要在后台手动指定一个数据列如下代码: dtRebatesReport.Co ...
- bzoj2599: [IOI2011]Race(点分治)
写了四五道点分治的题目了,算是比较理解点分治是什么东西了吧= = 点分治主要用来解决点对之间的问题的,比如距离为不大于K的点有多少对. 这道题要求距离等于K的点对中连接两点的最小边数. 那么其实道理是 ...
- JS 判断字串字节数,并截取长度
var matchWords; function notifyTextLength() { var inputNum = document.getElement ...
- C语言内存分配
(1)代码区(text segment).存放CPU执行的机器指令(machine instructions).通常,代码区是可共享的 (即另外的执行程序可以调用它),因为对于频繁被执行的程序,只 ...
- 基于struts2和hibernate的分页实现
在拜读了各位大牛的博客后,加以修改和添加总算是借鉴出了一个可行的分页实现.(●'◡'●) 话不多说,先贴两张效果图吧 接下来是实现代码: pagingDAOImpl.java public class ...
- 你的眼睛背叛你的心:解决 .NET Core 中 GetHostAddressesAsync 引起的 EnyimMemcached 死锁问题
在我们将站点从 ASP.NET + Windows 迁移至 ASP.NET Core + Linux 的过程中,目前遇到的最大障碍就是 —— 没有可用的支持 .NET Core 的 memcached ...