博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在LINQ中实现多条件联合主键LEFT JOIN
阅读量:5036 次
发布时间:2019-06-12

本文共 4078 字,大约阅读时间需要 13 分钟。

fROM:https://www.cnblogs.com/guyun/archive/2012/09/14/2684529.html

我昨天遇到一个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
             {
                 ... ...                            
             };
大功告成!

 

例子:

list = from goods in this.CurrentDLL.LoadEntities(a => true)

join goodsCategroy in GetCurrentDbSession.Tbl_OfficeSupplies_GoodsCategoryDLL.LoadEntities(a => true)
on goods.GoodsCategoryID equals goodsCategroy.ID into tmp
from tt in tmp.DefaultIfEmpty()
join goodsUnit in GetCurrentDbSession.Tbl_OfficeSupplies_GoodsUnitDLL.LoadEntities(a => true)
on goods.UnitID equals goodsUnit.ID into tmp1
from tt1 in tmp1.DefaultIfEmpty()
join goodsSpecifications in GetCurrentDbSession.Tbl_OfficeSupplies_GoodsSpecificationDLL.LoadEntities(a => true)
on goods.ID equals goodsSpecifications.GoodsID into tmp2
from tt2 in tmp2.DefaultIfEmpty()
join goodsStore in this.GetCurrentDbSession.Tbl_OfficeSupplies_GoodsStoreDLL.LoadEntities(a=>true)
on new { GoodsID= goods.ID, GoodsSpecificationID= tt2.ID } equals new { goodsStore.GoodsID, goodsStore.GoodsSpecificationID } into tmp3
from tt3 in tmp3.DefaultIfEmpty()

where tt.ID == new Guid(goodsCategoryID)

select new { GoodsID = goods.ID,
GoodsName = goods.Name,
GoodsCategoryName = tt.Name,
GoodsSpecificationID = tt2.ID,
GoodsSpecificationName = tt2.Name,
GoodsUnitName = tt1.Name,
ProcurementApplyCount = "",
ProcurementPricePer = "",
StoreCount = tt3.Count
};

 

修改为:

from goods in this.CurrentDLL.LoadEntities(a => true)

join goodsCategroy in GetCurrentDbSession.Tbl_OfficeSupplies_GoodsCategoryDLL.LoadEntities(a => true)
on goods.GoodsCategoryID equals goodsCategroy.ID into tmp
from tt in tmp.DefaultIfEmpty()
join goodsUnit in GetCurrentDbSession.Tbl_OfficeSupplies_GoodsUnitDLL.LoadEntities(a => true)
on goods.UnitID equals goodsUnit.ID into tmp1
from tt1 in tmp1.DefaultIfEmpty()
join goodsSpecifications in GetCurrentDbSession.Tbl_OfficeSupplies_GoodsSpecificationDLL.LoadEntities(a => true)
on goods.ID equals goodsSpecifications.GoodsID into tmp2
from tt2 in tmp2.DefaultIfEmpty()
join goodsStore in this.GetCurrentDbSession.Tbl_OfficeSupplies_GoodsStoreDLL.LoadEntities(a=>true)
on new { GoodsID= (Guid?)goods.ID, GoodsSpecificationID= (Guid?)tt2.ID } equals new { goodsStore.GoodsID, goodsStore.GoodsSpecificationID } into tmp3
from tt3 in tmp3.DefaultIfEmpty()

where tt.ID == new Guid(goodsCategoryID)

select new { GoodsID = goods.ID,
GoodsName = goods.Name,
GoodsCategoryName = tt.Name,
GoodsSpecificationID = tt2.ID,
GoodsSpecificationName = tt2.Name,
GoodsUnitName = tt1.Name,
ProcurementApplyCount = "",
ProcurementPricePer = "",
StoreCount = tt3.Count
};

条件中数据类型必须一致

转载于:https://www.cnblogs.com/liuqiyun/p/8610703.html

你可能感兴趣的文章
JavaScript动态清除
查看>>
SVN的忽略和只读使用方法学习记录
查看>>
smartupload 上传与下载(转载)
查看>>
Module
查看>>
Android TextView : “Do not concatenate text displayed with setText”
查看>>
SpringCloud Feign异常处理
查看>>
python接口自动化测试三十五:用BeautifulReport生成报告
查看>>
Microsoft Visual Studio is waiting for an internal operation to complete 解决方法
查看>>
Spark Streaming笔记整理(二):案例、SSC、数据源与自定义Receiver
查看>>
组播业务开通
查看>>
Java开发技术大揭底——让你认知自己技术上的缺陷,成为架构师
查看>>
MySQL:如何维护binlog?
查看>>
Android Studio 的常用设置
查看>>
Pythonic八荣八耻
查看>>
p2.BTC-数据结构
查看>>
封装自己的getClass
查看>>
python字符串的常用方法
查看>>
.net4.0、.net4.5、.net4.6 三者对系统的要求
查看>>
分布式下的session处理方式
查看>>
LeetCode(30) Substring with Concatenation of All Words
查看>>