Linq Join

1.准备数据源,我这边定义了一个实体,里面包含ID,Name,State

 public class NameModel
        {
            public int Id { get; set; }

            public string Name { get; set; }

            public string State { get; set; }
        }
List<NameModel> leftName = new List<NameModel>()
            {
                new NameModel() {Id=1,Name="我是1",State="4" },
                new NameModel() {Id=2,Name="我是2",State="4" },
                new NameModel() {Id=3,Name="我是3",State="4" },
                new NameModel() {Id=4,Name="我是4",State="4" },
                new NameModel() {Id=0,Name="我是新人",State="4" },
                new NameModel() {Id=0,Name="我是新人",State="4" }
            };


            List<NameModel> rigthName = new List<NameModel>(){
                new NameModel() {Id=1,Name="我是r1",State="4" },
                new NameModel() {Id=5,Name="我是R5",State="4" },
                new NameModel() {Id=3,Name="我是R3",State="4" },
                new NameModel() {Id=7,Name="我是R7",State="4" }
            };

2.我们来看看将2个集合通过Linq 来个内连接,这边通过2种方式来实现:

var list = from left in leftName
                       join rigth in rigthName on left.Id equals rigth.Id
                       select new
                       {
                           LeftID = left.Id,
                           LeftName = left.Name,
                           RigthID = rigth.Id,
                           RigthName = rigth.Name
                       };
            foreach (var l in list)
            {
                Console.WriteLine(
                        l.LeftID + "\t\t" +
                        l.LeftName + "\t\t" +
                        l.RigthID + "\t\t" +
                        l.RigthName + "\t\t"
                        );
            }
            Console.ReadKey();
var list = leftName.Join(rigthName, p => p.Id, x => x.Id, (p, x) => new
            {
                LeftID = p.Id,
                LeftName = p.Name,
                RigthID = x.Id,
                RigthName = x.Name
            });
            foreach (var l in list)
            {
                Console.WriteLine(
                        l.LeftID + "\t\t" +
                        l.LeftName + "\t\t" +
                        l.RigthID + "\t\t" +
                        l.RigthName + "\t\t"
                        );
            }
            Console.ReadKey();

二次运行的结果是一样的,如图

大家都知道链接包含内连和外连,外连又包含了左右连接,那么我们如何通过Linq来实现左右连接呢?这边就需要我们自己去写扩展方法来实现:

这边需要去定义扩展方法:

public static class JoinExtensions
    {
        /// <summary>
        /// 左连接
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TInner"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="source"></param>
        /// <param name="inner"></param>
        /// <param name="pk"></param>
        /// <param name="fk"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static IEnumerable<TResult> LeftJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
                                                                                        IEnumerable<TInner> inner,
                                                                                        Func<TSource, TKey> pk,
                                                                                        Func<TInner, TKey> fk,
                                                                                        Func<TSource, TInner, TResult> result)
        {
            IEnumerable<TResult> _result = Enumerable.Empty<TResult>();

            _result = from s in source
                      join i in inner
                      on pk(s) equals fk(i) into joinData
                      from left in joinData.DefaultIfEmpty()
                      select result(s, left);

            return _result;
        }

        /// <summary>
        /// 右连接
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TInner"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="source"></param>
        /// <param name="inner"></param>
        /// <param name="pk"></param>
        /// <param name="fk"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static IEnumerable<TResult> RightJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
                                                                                         IEnumerable<TInner> inner,
                                                                                         Func<TSource, TKey> pk,
                                                                                         Func<TInner, TKey> fk,
                                                                                         Func<TSource, TInner, TResult> result)
        {
            IEnumerable<TResult> _result = Enumerable.Empty<TResult>();

            _result = from i in inner
                      join s in source
                      on fk(i) equals pk(s) into joinData
                      from right in joinData.DefaultIfEmpty()
                      select result(right, i);

            return _result;
        }

        /// <summary>
        /// 合并
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TInner"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="source"></param>
        /// <param name="inner"></param>
        /// <param name="pk"></param>
        /// <param name="fk"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static IEnumerable<TResult> FullOuterJoinJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
                                                                                         IEnumerable<TInner> inner,
                                                                                         Func<TSource, TKey> pk,
                                                                                         Func<TInner, TKey> fk,
                                                                                         Func<TSource, TInner, TResult> result)
        {

            var left = source.LeftJoin(inner, pk, fk, result).ToList();
            var right = source.RightJoin(inner, pk, fk, result).ToList();

            return left.Union(right);


        }
    }

下面我们就实现下左链接:

var list = leftName.LeftJoin(rigthName, p => p.Id, x => x.Id, (p, x) => new
            {
                LeftID = p.Id,
                LeftName = p.Name,
                RigthID = x == null ? 0 : x.Id,
                RigthName = x == null ? "" : x.Name
            });
            foreach (var l in list)
            {
                Console.WriteLine(
                        l.LeftID + "\t\t" +
                        l.LeftName + "\t\t" +
                        l.RigthID + "\t\t" +
                        l.RigthName + "\t\t"
                        );
            }
            Console.ReadKey();

 

posted on 2017-03-31 12:00  唐景辉  阅读(596)  评论(0编辑  收藏  举报

导航