LinqMethod 实现 LeftJoin

Intro

有时候我们想实现 leftJoin 但是 Linq 提供的 Join 相当于是 INNER JOIN,于是就打算实现一个 LeftJoin 的扩展。

如果要使用到左连接,你需要使用 DefaultIfEmpty 来在没有join到数据的时候返回默认的集合

Solution

源代码:https://github.com/WeihanLi/WeihanLi.Common/blob/dev/src/WeihanLi.Common/Extensions/EnumerableExtension.cs#L149

/// <summary>
/// LeftJoin extension
/// </summary>
/// <typeparam name="TOuter">outer</typeparam>
/// <typeparam name="TInner">inner</typeparam>
/// <typeparam name="TKey">TKey</typeparam>
/// <typeparam name="TResult">TResult</typeparam>
/// <param name="outer">outer collection</param>
/// <param name="inner">inner collection</param>
/// <param name="outerKeySelector">outerKeySelector</param>
/// <param name="innerKeySelector">innerKeySelector</param>
/// <param name="resultSelector">resultSelector</param>
/// <returns></returns>
public static IEnumerable<TResult> LeftJoin<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector,
Func<TOuter, TInner, TResult> resultSelector)
{
return outer
.GroupJoin(inner, outerKeySelector, innerKeySelector, (outerObj, inners) => new
{
outerObj,
inners = inners.DefaultIfEmpty()
})
.SelectMany(a => a.inners.Select(innerObj => resultSelector(a.outerObj, innerObj)));
}

Use

使用起来和 Join 差不多,下面来展示一个示例

var posts = new[] { new { PostId = 1, PostTitle = "12333", }, new { PostId = 2, PostTitle = "12333", }, };
var postTags = new[] { new { PostId = 1, Tag = "HHH" } }; var result = posts.LeftJoin(postTags, p => p.PostId, pt => pt.PostId, (p, pt) => new { p.PostId, p.PostTitle, pt?.Tag }).ToArray();
Console.WriteLine(result.ToJson());

输出:

[{"PostId":1,"PostTitle":"12333","Tag":"HHH"},{"PostId":2,"PostTitle":"12333"}]

Memo

这是使用 LinqMethod 实现 LeftJoin,如果要使用 linq 查询语法实现左连接请参考这篇文章

Reference

LinqMethod 实现 LeftJoin的更多相关文章

  1. laravel 使用DB 鏈接leftJoin查詢

    $product_count = DB::table('fook_platform_orderrefund as a') ->leftJoin('fook_platform_orderinfo ...

  2. leftJoin鏈錶查詢

    //待使用券碼 $code_record_no = DB::table('fook_platform_order as a') ->select('o.code','o.apportion_bi ...

  3. MySql LeftJoin On 与 Where的差异

    [MySql LeftJoin On 与 Where的差异] 存在两张表: 分别插入数据: 下面的语句一与语句二会产生不同的结果: 语句一: 结果: 语句二: 结果: 为什么会存在差异,这和on与wh ...

  4. 不使用left-join等多表关联查询,只用单表查询和Java程序,简便实现“多表查询”效果

    上次我们提到,不使用left-loin关联查询,可能是为了提高效率或者配置缓存,也可以简化一下sql语句的编写.只写单表查询,sql真得太简单了.问题是,查询多个表的数据还是非常需要的. 因此,存在这 ...

  5. php laravel左连接leftJoin多条where语句

    通常情况下我们在做leftjoin连接时需要对不止一个条件进行进行匹配,这时候就需要使用闭包方式,如下: leftjoin('db', function ($join) {···}); leftjoi ...

  6. jpa多表leftjoin 查询,自定义返回结果

    sql代码 自定义返回结果 package com.cdp.ecosaas.coredb.uua.sync.vo; import java.io.Serializable; public class ...

  7. 减少leftJoin的使用 (转)

    作为开发,你是否经常碰到下面需要转换用户ID成用户名称的情况: 可惜你的这些业务表出于最少冗余设计要求,只有UserId,而没有UserName,这时你不得不破坏你一个类封装一个表的美好想法, 在你的 ...

  8. sql中join与left-join图解区别

      select a.* from YG_BRSYK a left join(SELECT DISTINCT SYXH, STUFF((SELECT '.'+MS FROM #lsb where SY ...

  9. linq join 左连接 leftjoin 多个on条件 where 条件

    var haveChange = from newScore in newScoreList join oldScore in oldScoreList on new{newScore.ExamId, ...

随机推荐

  1. mysql5.7中timestam默认值'0000-00-00 00:00:00'报错

    在mysql5.7中设置 timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'会报错: 解决办法: mysql> set sql_mode='NO_A ...

  2. Luogu P2210 Haywire 题解

    其实这题吧...有一种玄学解法 这题的要求的就是一个最小化的顺序 那么,我们就不进想到了一种显然的写法 就是random_shuffle 什么?这不是乱搞的非正解吗 然而,正如一句话说的好 一个算法, ...

  3. 了解angularjs中的生命周期钩子函数$onInit,$onChange,$onDestory,$postLink

     壹 ❀ 引 我在前面花了三篇文章用于介绍angularjs的指令directive,组件component,并专门花了一篇文章介绍directive与component的不同,其中提到在compon ...

  4. Java实现网络聊天中使用的socket API与Linux socket API之间的关系

    尝试着用Java编写一个网络聊天程序,发现总不如网上写的好,所以就直接引用了网上大神的优秀代码.代码如下: package project1; import java.awt.*; import ja ...

  5. chrome 插件备份

  6. python Json报错json.decoder.JSONDecodeError

    近期工作中遇到一个问题,执行json.loads(json_data)时,在json_data中加上tab空格后就报错,不加则不报错 一.json.loads(json_data) 报错json.de ...

  7. C sharp #004# 进度条与Timer

    饮水思源:金老师的自学网站 C#实现进度条异常简单,因为所有东西都已经封装好了. 只需要简单的拖拽: 写两行代码就完工了: private void timer1_Tick(object sender ...

  8. python distutils 基本打包与发布

    distutils 实现对package 包的发布 import math def showMsg(a): return a * a * a a = 10 print('%d 的三次方是 %d' % ...

  9. windows 下安装beego

    好久没写博客了,最近忙于一些杂事,看见有几个博友留言了,未能及时回复,稍后晚点回复诸位博友.不多说了,windows安装beego(请先确保git环境已安装并设置了git环境变量.这个简单网上很多教程 ...

  10. javaWeb综合案例

    商城案例 分模块:用户模块→ 分类模块 → 商品模块→购物车模块(最难)→ 订单模块 后台模块(往前台的数据的增删改查) 今日任务: 1用户注册 a注册完成 b给注册人发邮件 2用户激活 a 去邮箱激 ...