【本文纯个人理解,错误轻喷,非常希望能有大神指点】

A left (outer) join B on A.bid=B.id
上面这句话叫做左连接,原因是left(左)join(加入,连入)被译为左连接,所以,这是关于语法中关键字的翻译,而非连接原理,造成不能以为是从第一张表的左边连接。相反,它是从A表的右边开始连接的。原因很简单,比如一个普通的查询语句:select t.id TID from table1 t。后面的那个t是对table1的标记,再看TID它也是对t.id的标记,它们的功能是什么我们暂且不说,起码我们知道了sql的语法习惯是将附加的参数或者说明后置。这样我就再看上面的左连语句,就知道了left和join屁关系没有。语句的划分应该是:select A.* from A left join B on A.bid=B.id。outer没写,是因为所有的left join都是left outer join,right join类推!回到我们刚刚的那个语法,红色的部分代表了整个语句的操作及限定关键字,而left则是A的后置附加信息,它的意思是说,A是放在左边的,同样,你若把left换成Right就成了A放在右边,而如果后面加了Outer了呢,outer和join对是一对,他俩与inner join相对应,这下就好理解了,因为inner join将两张表里面所有的为空的记录都弃掉,所以,不需要哪个是左哪个是右,所以,A表后面的left或者right就被省略了,直接是A inner join B on。话说回来了,为什么要分左边呢?很简单,我们画表喜欢从左往右,左边定下了,再画右边,也就是,先把左边的表查出来,再把右边的取出来往上面拼,能拼多少拼多少。
 
【linq中的左右内连接】
linq的lambda
生成的sql
var queryLeft = from t in con.TRANSSECTION_BASEPRICE   
join u in con.SYS_STAFF on t.INPUT_MAN equals u.CODEUSER 
                                into TranNew
                                from tr in TranNew.DefaultIfEmpty()
                                select new
                                {
                                    t.DEST_PLACE,
                                    t.IF_VALID,
                                    t.INFO_ID,
                                    t.INPUT_TIME,
                                    INPUTMAN =tr==null?t.INPUT_MAN: tr.USERNAME
                                };
SELECT
1 AS "C1",
"Extent1"."DEST_PLACE" AS "DEST_PLACE",
"Extent1"."IF_VALID" AS "IF_VALID",
"Extent1"."INFO_ID" AS "INFO_ID",
"Extent1"."INPUT_TIME" AS "INPUT_TIME",
CASE WHEN ("Extent2"."ID" IS NULL) THEN "Extent1"."INPUT_MAN" ELSE "Extent2"."USERNAME" END AS "C2"
FROM "JSXW"."TRANSSECTION_BASEPRICE" "Extent1"
LEFT OUTER JOIN "JSXW"."SYS_STAFF" "Extent2" ON ("Extent1"."INPUT_MAN" = "Extent2"."CODEUSER") OR (("Extent1"."INPUT_MAN" IS NULL) AND ("Extent2"."CODEUSER" IS NULL))
var queryRight = from u in con.SYS_STAFF
                                 join t in con.TRANSSECTION_BASEPRICE on u.CODEUSER equals t.INPUT_MAN
                                 into unew
                                 from un in unew.DefaultIfEmpty()
                                 select new
                                 {
                                     un.DEST_PLACE,
                                     un.IF_VALID,
                                     un.INFO_ID,
                                     un.INPUT_TIME,
                                     INPUTMAN = u.USERNAME
                                 };
SELECT
1 AS "C1",
"Extent2"."DEST_PLACE" AS "DEST_PLACE",
"Extent2"."IF_VALID" AS "IF_VALID",
"Extent2"."INFO_ID" AS "INFO_ID",
"Extent2"."INPUT_TIME" AS "INPUT_TIME",
"Extent1"."USERNAME" AS "USERNAME"
FROM "JSXW"."SYS_STAFF" "Extent1"
LEFT OUTER JOIN "JSXW"."TRANSSECTION_BASEPRICE" "Extent2" ON ("Extent1"."CODEUSER" = "Extent2"."INPUT_MAN") OR (("Extent1"."CODEUSER" IS NULL) AND ("Extent2"."INPUT_MAN" IS NULL))
var queryInner = from t in con.TRANSSECTION_BASEPRICE
                                 join u in con.SYS_STAFF on t.INPUT_MAN equals u.CODEUSER
                                 select new
                                 {
                                     t.DEST_PLACE,
                                     t.IF_VALID,
                                     t.INFO_ID,
                                     t.INPUT_TIME,
                                     INPUTMAN = u.USERNAME
                                 };
SELECT
1 AS "C1",
"Extent1"."DEST_PLACE" AS "DEST_PLACE",
"Extent1"."IF_VALID" AS "IF_VALID",
"Extent1"."INFO_ID" AS "INFO_ID",
"Extent1"."INPUT_TIME" AS "INPUT_TIME",
"Extent2"."USERNAME" AS "USERNAME"
FROM "JSXW"."TRANSSECTION_BASEPRICE" "Extent1"
INNER JOIN "JSXW"."SYS_STAFF" "Extent2" ON ("Extent1"."INPUT_MAN" = "Extent2"."CODEUSER") OR (("Extent1"."INPUT_MAN" IS NULL) AND ("Extent2"."CODEUSER" IS NULL))

上面第二行,我图灰了的,是我在网上找到的right join。之所以图黑,是因为我觉得它不对,它其实也是左连接,只是把左右两张表顺序换了而已。我也未曾找到实现right join的Linq语句。而随着我的不断寻找,我越来越多的接触到一直说法,也就是,Linq与sql无关性。当然,意思并不是说linq与sql是没有关系的,相反,它们的关系非常大,但是,如果我们想linq的时候总是被sql的想法左右,会导致一些大家都不愿意看到的结果,比如有些本来很简单的工作我们把它弄得复杂甚至无法解决。因为我们面对的不再是【表】而是【对像】。

所以,我抛开了上面那种寻找左右联接与linq的思路,把自己想成一个不会sql的新人,去学习linq。而就在我学习linq的时候,发现linq中有许多sql里面根本没有的东西,而这些东西,通常是我们可以绕开sql中的复杂联接可以直接得到的。
而且我发现,linq中的join与sql中的join完全不是一个东西,或者说,它们根本没有血缘关系,有点儿像c与c++的感觉。
这样,我们就必须有一种新的思路,要找寻这条新的思路,我们要先看看我们之前为什么要寻找linq与sql的关系。
 
 
{查询数据的需求}--->{本来用sql的时候我们会写成的sql语句}--->{与sql语句相匹配的linq}
 
看吧,我们明知道sql转linq没有教程,linq转sql微软也没有明确给出算法,我们却还要这般折磨自己,何苦呢~~
那么我们就收回那颗自以为自己很牛逼的心,把我们的做法换一下:
{查询数据的需求}--->{解决需求的linq}
这种情况下,我们只会遇见两人种问题:一、linq完成不了我们的需求;二、效率问题。我们先来一个个看。第一个,我觉得问题不大,毕竟是一种语言,语言都是符合语言的规格的,没有它完不成的需求,只有它顾及不上的第二人问题。我们来看第二个问题,就是效率问题,这确实是一个大问题 ,因为,如果你写linq写得热血朝天,那么你完全可以认为,你的linq效率极低,我看见过一条linq语句,里面有几十个方法。linq也像sql一样,是一种需要构造的语言,所以,在写之前,我们必须要对linq进行深入的理解与学习,就像当初学习sql一样,看一条sql完全可以执行它大概的执行复杂度。好了,我们的问题出来了,就是学习linq!
linq之前我也有学习过,也有用过,但是,当时太年轻了,小菜b一杦,现在,知耻而后勇,进行再学习。后面我们继续把我的学习笔记送上来~~

从sql走向linq的我撞死在起点上的更多相关文章

  1. SQL、Linq、lamda表达式 同一功能不同写法

    一.SQL.Linq.lamda表达式 同一功能不同写法 SQL LINQ Lambda SELECT * FROM HumanResources.Employee from e in Employe ...

  2. SQL、LINQ、Lambda 三种用法(转)

    SQL.LINQ.Lambda 三种用法颜色注释: SQL LinqToSql Lambda QA1. 查询Student表中的所有记录的Sname.Ssex和Class列.select sname, ...

  3. 浅谈sql 、linq、lambda 查询语句的区别

    浅谈sql .linq.lambda 查询语句的区别 LINQ的书写格式如下: from 临时变量 in 集合对象或数据库对象 where 条件表达式 [order by条件] select 临时变量 ...

  4. sql转Linq的工具

    本文转载:http://www.cnblogs.com/huangxincheng/archive/2011/05/12/2044990.html 介绍一个小工具 Linqer   这些天写Linq挺 ...

  5. 步步学LINQ to SQL:使用LINQ检索数据【转】

    [IT168 专稿]该系列教程描述了如何采用手动的方式映射你的对象类到数据表(而不是使用象SqlMetal这样的自动化工具)以便能够支持数据表之间的M:M关系和使用实体类的数据绑定.即使你选择使用了自 ...

  6. Linq to Sql:N层应用中的查询(上) : 返回自定义实体

    原文:Linq to Sql:N层应用中的查询(上) : 返回自定义实体 如果允许在UI层直接访问Linq to Sql的DataContext,可以省去很多问题,譬如在处理多表join的时候,我们使 ...

  7. Linq To SQL和Linq To Object的批量操作InsertAllOnSubmit介绍

    无论是Linq To SQL还是Linq To Object(Entity frameworks)它们都为开发人员提供了Insert操作,及Insert集合操作,即InsertOnSubmit和Ins ...

  8. Configure Always On Availability Group for SQL Server on RHEL——Red Hat Enterprise Linux上配置SQL Server Always On Availability Group

    下面简单介绍一下如何在Red Hat Enterprise Linux上一步一步创建一个SQL Server AG(Always On Availability Group),以及配置过程中遇到的坑的 ...

  9. WAF——针对Web应用发起的攻击,包括但不限于以下攻击类型:SQL注入、XSS跨站、Webshell上传、命令注入、非法HTTP协议请求、非授权文件访问等

    核心概念 WAF Web应用防火墙(Web Application Firewall),简称WAF. Web攻击 针对Web应用发起的攻击,包括但不限于以下攻击类型:SQL注入.XSS跨站.Websh ...

随机推荐

  1. 【译】PHP之道(PHP the right way)

    刚入门的同学觉得自己能用PHP写出各种程序就很NB了,但其实作为一个专业程序员,你得有个全面点的知识结构.单元测试总得听过,文档工具总得用用,Xss总得会防.推荐大家把<PHP the righ ...

  2. Word中设置所有西文字体为新罗马

    如图所示,不用一个一个设置,在字体里直接设置细纹字体:Times New Roman ,中文字体不用管.

  3. 【微信】2.微信小程序开发--官方开发工具使用说明

    承接第一篇 =============================================== 关于微信小程序开发使用IDE,曾经自己动摇过. 到底是采用 微信官方小程序开发工具 WebS ...

  4. 【Node.js】4.从一个例子切入Node js的规范

    在开始之前,需要明确的一点就是, ①Node应用是由模块组成的,每一个文件都是一个模块,有自己的作用域. ②在这个文件里定义的变量,函数,类都是私有的,对其他的文件不可见. ③在一个文件中,也就是在一 ...

  5. mybatis 3简介

    http://www.mybatis.org/mybatis-3/zh/index.html

  6. linux下rar包的解压方法

    linux下rar包的解压方法 学习了:https://blog.csdn.net/yonggeit/article/details/72190246?utm_source=itdadao&u ...

  7. 转:全面分析 Spring 的编程式事务管理及声明式事务管理

    转:from: https://www.ibm.com/developerworks/cn/education/opensource/os-cn-spring-trans/

  8. DevExpress控件之GridControl、GridView

    GridControl对应标准WinForm里的GridView,相当于是一个控件,里面包含多个GridView也可以放其它的控件 禁止修改gridView1.OptionsBehavior.Edit ...

  9. VirtualBox修改现有虚拟磁盘大小

    VirtualBox装Ubuntu下载Android源代码分配的磁盘空间不够,修改磁盘大小必须进入VirtualBox安装目录使用VBoxmanager修改,执行: vboxmange modifyh ...

  10. PS如何使用自定义画笔

    1 没有杂色的白背景不用抠图,GIF格式的透明背景不用抠图,有背景但是不想抠图都可以直接定义为画笔.先选中需要定义的画笔(得到选区),然后单击编辑-定义画笔预设.   2 随后就可以找到我们的画笔工具 ...