我昨天遇到一个LINQ下使用多条件比对产生LEFT JOIN的问题,经过深入研究,终于解决了,也让我学到了新的东西,特地拿来分享。

实例:有一张库存异常变更视图KCYD,仓库ID[Ckid]和物品ID[SpxxId]是该视图的唯一约束。有一张物品表ITEM,物品ID[ITEM_ID]是主键。还有一张表是统计正品和次品库存数量的视图SPKC,仓库ID[CKID]和物品ID[SPXXID]是该视图的唯一约束。现在的要求是根据条件查询库存异常变更的物品信息,即要求KCYD左联ITEM再左联SPKC。KCYD和ITEM的公共字段是物品ID,KCYD和SPKC的公共字段是仓库ID和物品ID。

我原先想到的写法如下:

var query = from k in DBContext.KCYD
             join i in DBContext.ITEM
             on k.SPXXID equals i.ITEM_ID into g
             from gc in g.DefaultIfEmpty()
             join s in DBContext.SPKC
             on k.SpxxId equals s.SPXXID into g1
             from gc1 in g1.DefaultIfEmpty()
             where k.Ckid == gc1.CKID
             select new
             {
                 ... ...                            
             };

但是生成的SQL语句,KCYD和ITEM表是LEFT OUTER JOIN的,但是联SPKC表却变成了INNER JOIN,这是为啥呢,经过一番折腾下来,发现问题出在where k.Ckid == gc1.CKID,如果把这个条件去掉的话,那就成了LEFT OUTER JOIN了,然后我就在想这个条件应该放在哪呢,LINQ里面到底支不支持联合主键的问题呢,在网上搜了半天,发现可以用 on new {字段1,字段2} equals new {字段1,字段2} into g的方法,于是修改代码如下:

var query = from k in DBContext.KCYD
             join i in DBContext.ITEM
             on k.SPXXID equals i.ITEM_ID into g
             from gc in g.DefaultIfEmpty()
             join s in DBContext.SPKC
             on new {k.SpxxId,k.Ckid} equals new {s.SPXXID,s.CKID} into g1
             from gc1 in g1.DefaultIfEmpty()
             select new
             {
                 ... ...                            
             };

但是很不给力的是这样居然提示错误:The type arguments cannot be inferred from the query.
简直就是杯具,难道LINQ不支持这样搞?唉,在我绝望的时候同事为我看出了端倪,原来equals两边的参数字段名的大小写必须完全匹配。即完整代码如下:

var query = from k in DBContext.KCYD
             join i in DBContext.ITEM
             on k.SPXXID equals i.ITEM_ID into g
             from gc in g.DefaultIfEmpty()
             join s in DBContext.SPKC
             on new {SPXXID=k.SpxxId,CKID=k.Ckid} equals new {s.SPXXID,s.CKID} into g1
             from gc1 in g1.DefaultIfEmpty()
             select new
             {
                 ... ...                            
             };

大功告成!

在LINQ中实现多条件联合主键LEFT JOIN的更多相关文章

  1. EntityFramework中Mapper怎么定义联合主键?

    HasKey(m => new { m.StoreId, m.CarTypeId, m.CarLevel}) 用“new {}”联合主键以“,”分隔形式定义

  2. Hibernate注解映射联合主键的三种主要方式

    今天在做项目的时候,一个中间表没有主键,所有在创建实体的时候也未加组件,结果报以下错误: org.springframework.beans.factory.BeanCreationException ...

  3. 联合主键用Hibernate注解映射的三种方式

    第一.将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,再将该类注解为@Embeddable,最后在主类中(该类不包含联合主 ...

  4. hibernate 注解 联合主键映射

    联合主键用Hibernate注解映射方式主要有三种: 第一.将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,再将 该类注解 ...

  5. 联合主键用hibernate注解映射方式主要有三种:

    将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode 第一.将该类注解为@Embeddable,最后在主类中(该类不包含联合主键 ...

  6. Hibernate中用到联合主键的使用方法,为何要序列化,为何要重写hashcode 和 equals 方法

    联合主键用Hibernate注解映射方式主要有三种: 第一.将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,再将该类注解为 ...

  7. SQL Server中的联合主键、聚集索引、非聚集索引、mysql 联合索引

    我们都知道在一个表中当需要2列以上才能确定记录的唯一性的时候,就需要用到联合主键,当建立联合主键以后,在查询数据的时候性能就会有很大的提升,不过并不是对联合主键的任何列单独查询的时候性能都会提升,但我 ...

  8. JPA学习---第十二节:JPA中的联合主键

    1.定义实体类,代码如下: (1).将联合主键放到一个类中,代码如下: package learn.jpa.entity; import java.io.Serializable; import ja ...

  9. linq中的contains条件

    linq中的contains条件   在sql查询语句中,in 在linq 中用contains,并且contains前面是数组,而后面是列名,如: SELECT distinct BH FROM c ...

随机推荐

  1. RH033读书笔记(7)-Lab 8 Introduction to String Processing

    Lab 8 Introduction to String Processing Sequence 1: Exercises in string processing 1. Other than the ...

  2. window.history.back()的改进方法window.history.go()

    今天在做项目时,測试人员提出了一条bug,起初没当回事,在改动过程中才意识到其重要性,故记录下来. 依照需求,系统应该实现例如以下的功能:有三个关联的页面a.aspx(简称a),b.aspx(简称b) ...

  3. wind river hypervisor 2.0.2.1

    2692407267@qq.com,请注意很多其他内容http://user.qzone.qq.com/2692407267 wind river hypervisor 2.0.2.1 版权声明:本文 ...

  4. 一篇非常全面的freemarker教程

    copy自http://demojava.iteye.com/blog/800204 下面内容所有是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主 ...

  5. 华为上机题汇总----java

        以下华为上机题目都是网上整理得到的,代码都是自己调试过的,由于网上java答案较少,欢迎大家批评指正,也希望对准备华为上机的童鞋们有一点点帮助.在练习的过程中成长,加油!~~  第1题:输入字 ...

  6. android 常见的解决(mdpi、hdpi 、xhdpi、xxhdpi )屏幕调整

    查询到执行的system service后,就能够在dumpsys后面加上service的名字,查看指定的service信息. adb shell dumpsys activity adb shell ...

  7. 【Android进阶】Android程序与JavaScript之间的简单调用

    本篇将讲解一个简单的Android与JavaScript之间的简单调用的小程序 效果图 工程结构 HTMLActivity.java代码 package com.example.javatojs; i ...

  8. C# winform 实现 qq 在屏幕边缘 自动隐藏 鼠标移过去 移上去 又自动显示

    代码下载地址   http://download.csdn.net/detail/simadi/7677147

  9. cocos2d-x使用CCClippingNode实现跑马灯

    直接在代码,这是一个很好的包layer,可以直接调用  //原来白白 bool TestLayer::init() { CCSize size = CCDirector::sharedDirector ...

  10. 【Eclipse高速发展-文章插件】google V8,对于调试Nodejs

    安装的的时候能够通过 Help>Eclipse Marketplace的 搜索方式安装 或者 Help>Install New Software Name:googleV8 Locatio ...