Entityframework lambda Join Extension

public class DictionaryResult<TKey, TValue>
    {
        public TKey Key { get; set; }
        public IEnumerable<TValue> Values { get; set; }
    }

    public class JoinResult<TLeft, TRight>
    {
        public TLeft Left { get; set; }
        public TRight Right { get; set; }
    }
    public static class JoinExtension
    {
        /// <summary>
        /// 兩表JOIN,以Key匹配,僅返回交集
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="query"></param>
        /// <param name="another"></param>
        /// <param name="keySelector"></param>
        /// <param name="keySelector2"></param>
        /// <param name="resultSelector"></param>
        /// <returns></returns>
        public static IQueryable<TResult> InnerJoin<T1, T2, TKey, TResult>(this IQueryable<T1> query,
            IQueryable<T2> another,
            Expression<Func<T1, TKey>> keySelector,
            Expression<Func<T2, TKey>> keySelector2,
            Expression<Func<T1, T2, TResult>> resultSelector
            )
        {
            return query.Join(another, keySelector, keySelector2, resultSelector);
        }

        /// <summary>
        /// 兩表JOIN,左表爲主,以Key匹配右表數據。結果表示方式以左錶行爲Key,右錶行爲Values
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="query"></param>
        /// <param name="another"></param>
        /// <param name="keySelector"></param>
        /// <param name="keySelector2"></param>
        /// <returns></returns>
        public static IQueryable<DictionaryResult<T1, T2>> LeftJoinToDictionary<T1, T2, TKey>(this IQueryable<T1> query,
            IQueryable<T2> another,
            Expression<Func<T1, TKey>> keySelector,
            Expression<Func<T2, TKey>> keySelector2
            )
        {
            return query.GroupJoin(another, keySelector, keySelector2, (x, y) => new DictionaryResult<T1, T2> { Key = x, Values = y });
        }

        /// <summary>
        /// 兩表JOIN,左表爲主,以Key匹配右表數據。結果必有左表全部行,右表未有匹配行時其對應屬性爲NULL
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="query"></param>
        /// <param name="another"></param>
        /// <param name="keySelector"></param>
        /// <param name="keySelector2"></param>
        /// <param name="resultSelector"></param>
        /// <returns></returns>
        public static IQueryable<TResult> LeftJoin<T1, T2, TKey, TResult>(this IQueryable<T1> query,
            IQueryable<T2> another,
            Expression<Func<T1, TKey>> keySelector,
            Expression<Func<T2, TKey>> keySelector2,
            Expression<Func<JoinResult<T1, T2>, TResult>> resultSelector
            )
        {
            return query.LeftJoinToDictionary(another, keySelector, keySelector2)
                .SelectMany(x => x.Values.DefaultIfEmpty(), (x, y) => new JoinResult<T1, T2> { Left = x.Key, Right = y })
                .Select(resultSelector);
        }

        /// <summary>
        /// 兩表JOIN,右表爲主,以Key匹配左表數據。結果表示方式以右錶行爲Key,左錶行爲Values
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="query"></param>
        /// <param name="another"></param>
        /// <param name="keySelector"></param>
        /// <param name="keySelector2"></param>
        /// <returns></returns>
        public static IQueryable<DictionaryResult<T2, T1>> RightJoinToDictionary<T1, T2, TKey>(this IQueryable<T1> query,
            IQueryable<T2> another,
            Expression<Func<T1, TKey>> keySelector,
            Expression<Func<T2, TKey>> keySelector2
            )
        {
            return another.GroupJoin(query, keySelector2, keySelector, (x, y) => new DictionaryResult<T2, T1> { Key = x, Values = y });
        }


        /// <summary>
        /// 兩表JOIN,右表爲主,以Key匹配左表數據。結果必有右表全部行,左表未有匹配行時其對應屬性爲NULL
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="query"></param>
        /// <param name="another"></param>
        /// <param name="keySelector"></param>
        /// <param name="keySelector2"></param>
        /// <param name="resultSelector"></param>
        /// <returns></returns>
        public static IQueryable<TResult> RightJoin<T1, T2, TKey, TResult>(this IQueryable<T1> query,
            IQueryable<T2> another,
            Expression<Func<T1, TKey>> keySelector,
            Expression<Func<T2, TKey>> keySelector2,
            Expression<Func<JoinResult<T1, T2>, TResult>> resultSelector
            )
        {
            return another.RightJoinToDictionary(query, keySelector2, keySelector)
                .SelectMany(x => x.Values.DefaultIfEmpty(), (x, y) => new JoinResult<T1, T2> { Left = x.Key, Right = y })
                .Select(resultSelector);
        }
}
相關文章
相關標籤/搜索