这篇博文纪录一下:使用 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 表示对应关联实体。):

  1. where b select b
  2. no where select b
  3. where c select b
  4. 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]

总结:

  1. where b select b(EF6 √,EF7 X)
  2. no where select b(EF6 √,EF7 √)
  3. where c select b(EF6 √,EF7 X)
  4. 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 奇怪问题的更多相关文章

  1. 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 ...

  2. EntityFramework 7 Join Count LongCount 奇怪问题

    先吐槽一下,EF7 目前来说,真对的起现在的版本命名:"EntityFramework": "7.0.0-beta1". 这篇博文纪录一下:当 Linq 查询中 ...

  3. EntityFramework 7 Join Count LongCount 奇怪问题(已修复)

    问题说明: 博客问题纪录 Use EF7, Linq Join Count is error EF7 Code Commit EF7 版本(注意 rc): 旧版本:"EntityFramew ...

  4. 成功的拆开了SELECT里JOIN个SELECT是啥

    SELECT * FROM table JOIN table ON a=b ----------------------- JOIN (SELECT* FROM table JOIN table ON ...

  5. 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 ...

  6. 爱与恨的抉择:ASP.NET 5+EntityFramework 7

    EF7 的纠缠 ASP.NET 5 的无助 忘不了你的好 一开始列出的这个博文大纲,让我想到了很久之前的一篇博文:恋爱虽易,相处不易:当EntityFramework爱上AutoMapper,只不过这 ...

  7. ASP.NET 5+EntityFramework 7

    爱与恨的抉择:ASP.NET 5+EntityFramework 7   EF7 的纠缠 ASP.NET 5 的无助 忘不了你的好 一开始列出的这个博文大纲,让我想到了很久之前的一篇博文:恋爱虽易,相 ...

  8. 对于SQL的Join,在学习起来可能是比较乱的。我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚。Coding Horror上有一篇文章,通过文氏图 Venn diagrams 解释了SQL的Join。我觉得清楚易懂,转过来。

     对于SQL的Join,在学习起来可能是比较乱的.我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚.Codi ...

  9. MySQL SELECT语法(三)JOIN语法详解

    源自MySQL 5.7 官方手册:13.2.9.2 JOIN Syntax SELECT select_expr From table_references JOIN... WHERE... 如上所示 ...

随机推荐

  1. 媒体查询(pc端,移动端不同布局)

    媒体查询语法: 1.内联写法:and之后必须有空格@media screen and (min-width:960px //判断浏览器大小条件){body{background:red} //常规的样 ...

  2. CSS hack技巧大全

    ——作者:吴雷君 兼容范围: IE:6.0+,FireFox:2.0+,Opera 10.0+,Sarari 3.0+,Chrome 参考资料: 各游览器常用兼容标记一览表: 标记 IE6 IE7 I ...

  3. 谈 CSS 模块化

    以前看过模块化的相关资料以及解释,对模块化有了一个表皮的了解,自己也做了一些相关的实践,由于接触到的项目交小,所以也没能更好的去体现和理解模块化,但总体还是有那么一些感悟,但是如果要说怎么才能算是好的 ...

  4. mark

    *求数根公式:a的数根b = (a-1) % 9 + 1; *约瑟环问题:f1 = 0; 第i个(i>1),f = (f+m) %i;

  5. 使用C#和Excel进行报表开发(三)-生成统计图(Chart)

    有的Web项目选用Excel作为报表方案,在服务器端生成Excel文件,然后传送到客户端,由客户端进行打印.在国内的环境下,相对PDF方式,Excel的安装率应该比pdf阅读器的安装率要高,同时,微软 ...

  6. 一鼓作气 博客--第三篇 note3

    1 推荐读书消费者行为学 -商业的本质,APP得到,5分钟商学院 2定义字典 dic={'name':haibao,'age':18} 3字典的基本操作--查询 dic={'name':'haibao ...

  7. 浅谈Js原型的理解

    一.js中的原型毫无疑问一个难点,学习如果不深入很容易就晕了!    在参考了多方面的资料后,发现解释都太过专业,对于很多还没有接触过面向对象    语言的小白来说,有理解不了里面的专有名词!如果你没 ...

  8. C#程序代码分析(第三周)

    刚开始看到这段程序,都不知道是什么东西,问过室友才知道是C#程序:但对C#一点都不了解,最基本的项目建设都不会,在室友的帮助下,以及在网上搜了一些资料,勉强算是完成了此次作业吧. using Syst ...

  9. XMPP iOS客户端实现二:xcode项目配置

    1.下载XMPPFramework,下载地址:https://github.com/robbiehanson/XMPPFramework 2.创建项目并将XMPP库引入: 3.添加需要的库文件: 4. ...

  10. VS轻松开发Node.js应用

    PTVS开发团队又开发出一款可以在VS里编写Node.js应用程序的插件--NTVS(Node.js Tools for Visual Studio),开发者可以在VS里轻松开发Node.js应用. ...