Linq实现InnerJoin&LeftJoin


public static class LinqEx
    {
        public static IEnumerable LeftExcludingJoin(this IEnumerable source,
                                                    IEnumerable inner,
                                                    Func pk,
                                                    Func fk,
                                                    Func result)
            where TSource : class
            where TInner : class
        {
            IEnumerable _result = Enumerable.Empty();

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

            return _result;
        }

        public static IEnumerable LeftJoin(this IEnumerable source,
                                                    IEnumerable inner,
                                                    Func pk,
                                                    Func fk,
                                                    Func result)
            where TSource : class
            where TInner : class
        {
            IEnumerable _result = Enumerable.Empty();

            _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;
        }

        public static IEnumerable RightExcludingJoin(this IEnumerable source,
                                                        IEnumerable inner,
                                                        Func pk,
                                                        Func fk,
                                                        Func result)
            where TSource : class
            where TInner : class
        {
            IEnumerable _result = Enumerable.Empty();

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

            return _result;
        }

        public static IEnumerable FulltExcludingJoin(this IEnumerable source,
                                                            IEnumerable inner,
                                                            Func pk,
                                                            Func fk,
                                                            Func result)
            where TSource : class
            where TInner : class
        {
            var left = source.LeftJoin(inner, pk, fk, result).ToList();
            var right = source.RightExcludingJoin(inner, pk, fk, result).ToList();

            return left.Union(right);
        }

        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 

        public static IEnumerable InnerJoin(this IEnumerable source,
                                                    IEnumerable inner,
                                                    Func pk,
                                                    Func fk,
                                                    Func result)
            where TSource : class
            where TInner : class
        {
            IEnumerable _result = Enumerable.Empty();

            _result = from s in source
                      join i in inner
                      on pk(s) equals fk(i)
                      select result(s, i);

            return _result;
        }

    }


测试代码:

List orders = new List();
List details = new List();
orders.Add(new ProductOrder { OrderID = "2021", OrderDate = DateTime.Now });
orders.Add(new ProductOrder { OrderID = "2022", OrderDate = DateTime.Now });

details.Add(new ProductOrderDetail { OrderID = "2021", ProductCode = "A273197" });
details.Add(new ProductOrderDetail { OrderID = "2021", ProductCode = "A273198" });
details.Add(new ProductOrderDetail { OrderID = "2020", ProductCode = "A273196" });
details.Add(new ProductOrderDetail { OrderID = "2020", ProductCode = "A273195" });


var mm = orders.LeftJoin(details, x => x.OrderID, y => y.OrderID, (x, y) => new { x, y }).ToList();
var tt = orders.InnerJoin(details, x => x.OrderID, y => y.OrderID, (x, y) => new { x, y }).ToList();