I always considered Left Outer Join in LINQ to be complex until today when I had to use it in my application. I googled and the firstresult gave a very nice explanation. The only difference between ordinary joins (inner joins) and left joins in LINQ is the use of “join into” and “DefaultIfEmpty()” expressions.

Consider this very simple query (Assuming a scenario that not all the TimesheetLines are associated with a Job)

1
2
3
Select TL.EntryDate, TL.Hours, J.JobName
From TimeSheetLines TL
Left Join Jobs J on TL.JobNo=J.JobNo

A LINQ query using inner join is

1
2
3
4
5
6
7
8
9
10
11
var lines =
    from tl in db.TimeSheetLines
    join in db.Jobs on tl.JobNo equals j.JobNo
    where tl.ResourceNo == resourceNo
 
    select new
    {
        EntryDate = tl.EntryDate,
        Hours = tl.Hours,
        Job = j.JobName
    };

And a LINQ query performing left join is

1
2
3
4
5
6
7
8
9
10
11
12
var lines =
    from tl in db.TimeSheetLines
    join in db.Jobs on tl.JobNo equals j.JobNo into tl_j
    where tl.ResourceNo == resourceNo
 
    from j in tl_j.DefaultIfEmpty()
    select new
    {
        EntryDate = tl.EntryDate,
        Hours = tl.Hours,
        Job = j.JobName
    };

Notice that the only difference is the use of “into” with the join statement followed by reselecting the result using “DefaultIfEmpty()” expression. And here’s the generated SQL for the above LINQ expression.

1
2
3
4
SELECT [t0].[EntryDate] as [EntryDate], [t0].[Hours] as [Hours], [t1].[JobName] AS [Job]
FROM [dbo].[TimeSheetLine] AS [t0]
LEFT OUTER JOIN [dbo].[Jobs] AS [t1] ON [t0].[JobNo] = [t1].[JobNo]
WHERE [t0].[ResourceNo] = @p0

Another LINQ version which is more compact is:

1
2
3
4
5
6
7
8
9
var lines =
    from tl in db.TimeSheetLines
    from j in db.Jobs.Where(j=>j.JobNo == tl.JobNo).DefaultIfEmpty()
    select new
    {
        EntryDate = tl.EntryDate,
        Hours = tl.Hours,
        Job = j.JobName
    };

Similarly, this concept can be expanded for multiple left joins. Assuming that a TimeSheetLine will either have a JobNo or an IndirectCode, consider this SQL query:

1
2
3
4
Select TL.EntryDate, TL.Hours, J.JobName, I.IndirectName
From TimeSheetLines TL
Left Join Jobs J on TL.JobNo=J.JobNo
Left Join Indirects I on TL.IndirectCode=I.IndirectCode

The equivalent LINQ query is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var lines =
    from tl in db.TimeSheetLines
    join j in db.Jobs      on tl.JobNo        equals j.JobNo         into tl_j
    join i in db.Indirects on tl.IndirectCode equals i.IndirectCode  into tl_i
    where tl.ResourceNo == resourceNo
 
    from j in tl_j.DefaultIfEmpty()
    from i in tl_i.DefaultIfEmpty()
    select new
    {
        EntryDate = tl.EntryDate,
        Hours = tl.Hours,
        Job = j.JobName,
        Indirect = i.IndirectName,
    };

And the generated SQL is:

1
2
3
4
SELECT [t0].[EntryDate] as [EntryDate], [t0].[Hours] as [Hours], [t1].[JobName] AS [Job], [t2].[IndirectName] As [Indirect]
LEFT OUTER JOIN [dbo].[Jobs] AS [t1] ON [t0].[JobNo] = [t1].[JobNo]
LEFT OUTER JOIN [dbo].[Indirects] AS [t2] ON [t0].[IndirectCode] = [t2].[IndirectCode]
WHERE [t0].[ResourceNo] = @p0

That’s all, left outer joins in LINQ are as easy as in T-SQL. Happy joining.

Update:
Notice that this post describes the approach to perform a Left Outer Join in LINQ To SQL as well as Entity Framework (version 4). The same is not true for Entity Framework version 3.5 since it does not support the DefaultIfEmpty keyword. To perform Left Outer Joins with Entity Framework 3.5, we need to create appropriate relationships (e.g 0..1 to 0..Many) in our Entity Model and they will be automatically translated into TSQL’s Left Join clause.

come form: https://smehrozalam.wordpress.com/2009/06/10/c-left-outer-joins-with-linq/

转载: C#: Left outer joins with LINQ的更多相关文章

  1. Lerning Entity Framework 6 ------ Joins and Left outer Joins

    Joins allow developers to combine data from multiple tables into a sigle query. Let's have a look at ...

  2. How Distributed Outer Joins on PostgreSQL with Citus Work

    转自: https://docs.citusdata.com/en/v7.5/articles/outer_joins.html SQL is a very powerful language for ...

  3. [转载代码]VB.NET 中查询 Linq to SQL 执行时的SQL语句

    在搜索使用LINQ TO SQL 添加数据后获得自增长ID的方法时,发现C#可以使用DebuggerWritter把使用Linq to SQL执行的SQL语句显示到即时窗口,于是在网上搜索到在VB.N ...

  4. Mysql 5.6 新特性(转载)

    本文转载自 http://blog.csdn.net/wulantian/article/details/29593803 感谢主人的辛苦整理 一,安全提高 1.提供保存加密认证信息的方法,使用.my ...

  5. Hive学习笔记【转载】

    本文转载自:http://blog.csdn.net/haojun186/article/details/7977565 1.  HIVE结构 Hive 是建立在 Hadoop 上的数据仓库基础构架. ...

  6. LINQ 常规实践总结

    1.Linq 执行多列排序 OrderBy的意义是按照指定顺序排序,连续两次OrderBy,后面一个有可能会打乱前面一个的排序顺序,可能与预期不符. 要实现sql中的order by word,nam ...

  7. linq用法整理

    linq用法整理 普通查询 var highScores = from student in students where student.ExamScores[exam] > score se ...

  8. LINQ之路15:LINQ Operators之元素运算符、集合方法、量词方法

    本篇继续LINQ Operators的介绍,包括元素运算符/Element Operators.集合方法/Aggregation.量词/Quantifiers Methods.元素运算符从一个sequ ...

  9. LINQ之路13:LINQ Operators之连接(Joining)

    Joining IEnumerable<TOuter>, IEnumerable<TInner>→IEnumerable<TResult> Operator 说明 ...

随机推荐

  1. 递归---NYOJ-176 整数划分(二)和NYOJ-279队花的烦恼二

    这道题目的递归思想和第一个题差不多, 主要思想是:func(n, m)的作用是将n划分为m个. 1. 如果n < m 的时候肯定是不能划分的,所以就返回0 2. 如果m = 1 或者 n = m ...

  2. Ecstore内置表单验证?

       

  3. ASP.Net MVC 之FileResult

    FileResult是一个基于文件的ActionResult,利用FileResult我们可以很容易地将从某个物理文件的内容响应给客户端.ASP.NET MVC定义了三个具体的FileResult,分 ...

  4. Nginx配置文件nginx.conf详解(转)

    #定义Nginx运行的用户和用户组 user www www; #nginx进程数,建议设置为等于CPU总核心数. worker_processes 8; #全局错误日志定义类型,[ debug | ...

  5. ajax调用action后返回list给list.jsp,显示为xml文档

    struts2中使用的是map来保存数据的,所以这里绑定的值是key和value1 <?xml version="1.0" encoding="UTF-8" ...

  6. Java下载Servlet Demo

    request.setCharacterEncoding("utf-8"); String name=request.getParameter("name"); ...

  7. 使用 phpMyAdmin无法登录mysql的问题

    今天使用使用phpmyadmin时出现了以下错误: (1)第一次时: 当配置文件config.inc.php里的配置项是: $cfg['Servers'][$i]['host'] = 'localho ...

  8. IE6浏览器兼容问题及部分解决方案(网上整理)

    作为一个初涉前端技术的IT菜鸟,IE浏览器的兼容问题是一个不得不跨越的坎.为了能够在不同浏览器达到同样的显示效果,就不得不花心思想出办法实现兼容.由于各大主流浏览器内核不同,各自的实现标准有所差异,因 ...

  9. 04 - 替换vtkDataObject中的GetPipelineInformation 和GetExecutive 方法 VTK 6.0 迁移

    VTK6 引入了许多不兼容的变.其中之一是删除vtkDataObject中所有有关管道的方法.其中的两个方法就是GetPipelineInformation() 和 GetExecutive().这些 ...

  10. Unity3D添加Admob广告

    重要提示:             貌似play2014年8月之后不会再支持admob的SDK方式的广告了.github上已经有了 Unity AdMob (Google Play Services) ...