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

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桌面版GUI网络配置工具NetworkManager的命令行工具nm-tool无法使用的问题

    说明: 1.Ubuntu中分桌面版和服务器版,而这两个版本在网络管理方面使用的工具都不一样,尤其是在桌面版,使用了NetworkManager进行管理. 2.服务器版使用的是命令行配置,而桌面版包含了 ...

  2. TDD的iOS开发初步以及Kiwi使用入门

    测试驱动开发(Test Driven Development,以下简称TDD)是保证代码质量的不二法则,也是先进程序开发的共识.Apple一直致力于在iOS开发中集成更加方便和可用的测试,在Xcode ...

  3. 【power designer】使用power designer编辑pdm物理模型图时,为字段添加中文备注

    如下图: 1.双击下图修改 应用如下 2.为数据列添加备注属性 然后为备注列添加 中文备注 [注意,这里有个小技巧,如果光标已经点进去这个单元格,是不能复制进去文字的,但是第一次点击单元格,是可以复制 ...

  4. scala测试框架:scalatest

    api文档:http://tool.oschina.net/apidocs/apidoc?api=scalatest-1.7.2 trait Assertions:http://tool.oschin ...

  5. Unable to list target platforms. Please make sure the android sdk path is correct. See the Console for more details.

    在android上发布遇到 androidSDK无法找到的问题 http://www.jianshu.com/p/fe4c334ee9fe

  6. 自己定义JSTL函数

    因为 jstl 函数 字符串替换不支持正則表達式 所以想用java String的 replaceAll进行替换 须要自己定义 jstl函数 首先写类 package com.salesmanb2b. ...

  7. JWT笔记(2)

    上文对JWT模块进行了一个简单的分析.这篇文章稍微做出一些深入的了解. 一,Header篡改攻击 因为JWT的Header是强制有效并且是明文传输(Base64URL编码,几乎等同于明文).那么恶意用 ...

  8. CKEditor+SWFUpload实现功能较为强大的编辑器(三)---后台接收图片流程

    在前台配置完CKEditor和SWFUpload之后就可以满足基本的需求了 在这里,我配置的接收异步上传的图片的页面为upload.ashx 在这个ashx中对上传的图片处理的流程如下: contex ...

  9. python实现scrapy爬取图片到本地时的sha1摘要算法文件名

    2017-03-29 Scrapy爬图片到本地应该会给图片自动生成sha1摘要算法文件名,我第一次用scrapy也不清楚太多,就在程序里自己写了一段实现这一功能的代码.需import hashlib ...

  10. ecshop_商品描述远程图片自动本地化插件

    解压缩文件,覆盖 ecshop 的 \includes\fckeditor文件夹. 这样在后台添加商品的商品详细描述,编辑器最后一个按钮就是自动下载 远程图片到你的网站空间,这样可防止对方网站图片失效 ...