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

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. microsoft-sql-server release-notes

    https://docs.microsoft.com/en-us/sql/release-notes/microsoft-sql-server

  2. MongoDB 聚合Group(一)

    原文:http://blog.csdn.net/congcong68/article/details/45012717 一.简介 db.collection.group()使用JavaScript,它 ...

  3. XCode下的iOS单元测试

    XCode 内置了 OCUnit 单元测试框架,但目前最好用的测试框架应该是 GHUnit.通过 GHUnit + OCMock 组合,我们可以在 iOS 下进行较强大的单元测试功能.本文将演示如何在 ...

  4. UVa1347 Tour

    /*----UVa1347 ---首相两边方向走不方便,可以看做:两个人同时从最左边出发,沿着两条不同路径走到终点,除了起点和中点外 其他点恰好被走过一遍 ---用dp[i][j]表示1-max(i, ...

  5. 安全小测试:介绍一个简单web安全知识测试的网站

    https://websecurity.firebaseapp.com/ 一次测试一共7道题,最后有答案,可以反复做,每次随机抽题

  6. 怎样从server获取图片

    今天写了安卓程序与server通信.当中须要从server获取图片.本来以为下载流.处理文件流非常复杂.结果几句话就轻松搞定了.如今记在这里. // (2014.5.1第一种方法)通过server返回 ...

  7. c#中的构造方法

    c#基础--类的构造方法   当实例化一个类时,系统会自动对这个类的属性进行初始化 数字型初始化成0/0.0 string类型初始化成null char类型初始化成\0 构造器就是构造方法,能够被重载 ...

  8. Solr 创建core 从MySql数据库中导入数据

    一.创建数据表和数据 在MySql数据中创建mysolrInfo表, 创建字段 id 主键,自动增加 pname :姓名 age :年龄 addtime :增加时间 增加几条数据 二.创建core 当 ...

  9. 命令行设置IE代理

    IE代理可以在注册表中设置,所以用DOS修改注册表,可以达到目的.方法一:注册表文件:REGEDIT4[HKEY_CURRENT_USER\Software\Microsoft\Windows\Cur ...

  10. 【HTML 元素】嵌入另一张HTML文档、通过插件嵌入内容、嵌入数字表现形式

    1.嵌入另一张HTML文档 iframe 元素允许在现有的HTML文档中嵌入另一张文档.下面代码展示了iframe元素的用法: <!DOCTYPE html> <html lang= ...