Esempio n. 1
0
        private static bool HasIndexablePropertyOnLeft <TSource>(Expression leftSide,
                                                                 IndexableCollection <TSource> sourceCollection,
                                                                 out MemberExpression memberExpr)
        {
            memberExpr = null;
            var mex = leftSide as MemberExpression;

            if (leftSide.NodeType == ExpressionType.Call)
            {
                var call = leftSide as MethodCallExpression;
                if (call != null)
                {
                    if (call.Method.Name.EqualTo("CompareString"))
                    {
                        mex = call.Arguments[0] as MemberExpression;
                    }
                }
            }

            if (mex == null)
            {
                return(false);
            }

            memberExpr = mex;
            return(sourceCollection.PropertyHasIndex(mex.Member.Name));
        }
Esempio n. 2
0
        /// <summary>
        /// 인덱싱된 시퀀스에서 일치하는 키를 기준으로 두 시퀀스의 요소를 연관시킵니다. 지정한 IEqualityComparer{TKey}를 사용하여 키를 비교합니다.
        /// </summary>
        public static IEnumerable <TResult> Join <TOuter, TInner, TKey, TResult>(
            this IndexableCollection <TOuter> outer,
            IndexableCollection <TInner> inner,
            Expression <Func <TOuter, TKey> > outerKeySelector,
            Expression <Func <TInner, TKey> > innerKeySelector,
            Func <TOuter, TInner, TResult> resultSelector,
            IEqualityComparer <TKey> comparer)
        {
            outer.ShouldNotBeNull("outer");
            inner.ShouldNotBeNull("inner");
            outerKeySelector.ShouldNotBeNull("outerKeySelector");
            innerKeySelector.ShouldNotBeNull("innerKeySelector");
            resultSelector.ShouldNotBeNull("resultSelector");

            bool hasIndex = false;

            if (innerKeySelector.NodeType == ExpressionType.Lambda &&
                innerKeySelector.Body.NodeType == ExpressionType.MemberAccess &&
                outerKeySelector.NodeType == ExpressionType.Lambda &&
                outerKeySelector.Body.NodeType == ExpressionType.MemberAccess)
            {
                var memberExpressionInner = (MemberExpression)innerKeySelector.Body;
                var memberExpressionOuter = (MemberExpression)outerKeySelector.Body;
                var innerIndex            = new MultiMap <int, TInner>();
                var outerIndex            = new MultiMap <int, TOuter>();

                if (inner.PropertyHasIndex(memberExpressionInner.Member.Name) &&
                    outer.PropertyHasIndex(memberExpressionOuter.Member.Name))
                {
                    innerIndex = inner.GetIndexByProperty(memberExpressionInner.Member.Name);
                    outerIndex = outer.GetIndexByProperty(memberExpressionOuter.Member.Name);
                    hasIndex   = true;
                }

                if (hasIndex)
                {
                    foreach (int outerKey in outerIndex.Keys)
                    {
                        IList <TOuter> outerGroup = outerIndex[outerKey];
                        IList <TInner> innerGroup;
                        if (innerIndex.TryGetValue(outerKey, out innerGroup))
                        {
                            // join on the GROUPS based on key result
                            IEnumerable <TInner>  inners  = innerGroup.AsEnumerable();
                            IEnumerable <TOuter>  outers  = outerGroup.AsEnumerable();
                            IEnumerable <TResult> results = outers.Join(inners, outerKeySelector.Compile(),
                                                                        innerKeySelector.Compile(),
                                                                        resultSelector, comparer);
                            foreach (TResult resultItem in results)
                            {
                                yield return(resultItem);
                            }
                        }
                    }
                }
            }

            if (hasIndex == false)
            {
                if (IsDebugEnabled)
                {
                    log.Debug("Index가 없으므로 System.Linq.Enumerable.Join()을 수행합니다. ");
                }

                var inners  = inner.AsEnumerable();
                var outers  = outer.AsEnumerable();
                var results = outers.Join(inners, outerKeySelector.Compile(),
                                          innerKeySelector.Compile(),
                                          resultSelector, comparer);

                foreach (var resultItem in results)
                {
                    yield return(resultItem);
                }
            }
        }