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

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. Ubuntu 16.04出现:dpkg: 处理软件包 xxx (--configure)时出错:

    如下所示: 解决方法: #将info文件夹更名 sudo mv /var/lib/dpkg/info /var/lib/dpkg/info_old #再新建一个新的info文件夹 sudo mkdir ...

  2. UBIFS介绍 - MTD网站

    转:http://blog.csdn.net/kickxxx/article/details/6583463 目录(?)[-] Big red note Overview Scalabity Writ ...

  3. Swift入门(一)——基本的语法

    近期開始学习swift.把学习的过程和总结整理成一个系列.方便日后回想总结. 基本的语法 基础语法 swift中每一行结束后不须要加分号.多个语句在同一行内须要用分好隔开 //表示凝视.或者用/* - ...

  4. Http协议三次握手过程

    Http协议三次握手过程   TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: ...

  5. 在pos:a元素不设定宽度的情况下,他的最大宽度是受父元素的宽度所限制的。

    <div style="width:80px;height:50px;position:relative;left:50px;"> <ul style=" ...

  6. JavaWeb项目实现文件下载

    File file = new File(path);// path是根据日志路径和文件名拼接出来的 String filename = file.getName();// 获取日志文件名称 Inpu ...

  7. spring-hadoop-samples

    官方的spring-hadoop-samples的demo 写的还是挺好的,值得学习. 官网地址: http://projects.spring.io/spring-hadoop/#quick-sta ...

  8. 关于批量插入数据之我见(100万级别的数据,mysql)

    因前段时间去面试,问到怎样高效向数据库插入10万条记录,之前没处理过类似问题.也没看过相关资料,结果没答上来,今天就查了些资料.总结出三种方法: 測试数据库为mysql!!! 方法一: public ...

  9. iOS 设置导航栏 返回按钮文字隐藏

    //隐藏返回按钮文字 [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) f ...

  10. liunx下安装第三方Python(PIP安装)

    wget https://pypi.python.org/packages/source/p/pip/pip-6.0.8.tar.gz $ tar zvxf pip-6.0.8.tar.gz $ cd ...