Exemple #1
0
        public KeyInfoBase(
            MemberInfo[] entityKeyMembers,
            SortOrder[] sortOrders,
            IComparer <TKey> keyComparer,
            IKeyInfoHelper helper)
        {
            this.entityKeyMembers = entityKeyMembers;

            if (sortOrders == null)
            {
                sortOrders = Enumerable
                             .Repeat(SortOrder.Ascending, helper.GetMemberCount())
                             .ToArray();
            }

            this.sortOrders = sortOrders;

            this.keyComparer = keyComparer;
            this.keySelector = KeyExpressionHelper
                               .CreateKeySelector <TEntity, TKey>(entityKeyMembers, helper)
                               .Compile();
            this.keyEmptinessDetector = KeyExpressionHelper
                                        .CreateKeyEmptinessDetector <TEntity, TKey>(helper)
                                        .Compile();
        }
Exemple #2
0
        protected IQueryable <TEntity> CreateQuery(TPrimaryKey key)
        {
            var param   = Expression.Parameter(typeof(TEntity));
            var members = this.PrimaryKeyIndex.KeyInfo.EntityKeyMembers;

            var selector =
                KeyExpressionHelper.CreateKeySelector(param, members, this.KeyInfoHelper);

            var predicate =
                Expression.Lambda <Func <TEntity, bool> >(
                    Expression.Equal(
                        selector,
                        Expression.Constant(key)),
                    param);

            return(((IQueryable <TEntity>) this).Where(predicate));
        }
Exemple #3
0
        private static Func <TFrom, TTo> CreateConversion <TFrom, TTo>(
            IKeyInfo <TFrom> fromKeyInfo,
            IKeyInfo <TTo> toKeyInfo,
            int[] mapping)
        {
            IKeyInfoHelper from = GetKeyInfoHelper(fromKeyInfo);
            IKeyInfoHelper to   = GetKeyInfoHelper(toKeyInfo);

            ParameterExpression keyParam = Expression.Parameter(fromKeyInfo.KeyType);

            Expression body =
                KeyExpressionHelper.CreateKeyConversionExpression(
                    keyParam,
                    toKeyInfo.EntityKeyMembers,
                    mapping,
                    from,
                    to);

            return(Expression.Lambda <Func <TFrom, TTo> >(body, keyParam).Compile());
        }
        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            if (!node.Method.IsGenericMethod ||
                node.Method.GetGenericMethodDefinition() != this.Original)
            {
                // Not GroupJoin
                return(base.VisitMethodCall(node));
            }

            ConstantExpression secondExpression = node.Arguments[1] as ConstantExpression;

            if (secondExpression == null)
            {
                // Not constant expression
                return(base.VisitMethodCall(node));
            }

            ITable table = secondExpression.Value as ITable;

            if (table == null)
            {
                // Not table
                return(base.VisitMethodCall(node));
            }

            LambdaExpression secondKeySelector =
                ExpressionHelper.SkipQuoteNode(node.Arguments[3]) as LambdaExpression;

            Type           keyType = secondKeySelector.Body.Type;
            IKeyInfoHelper helper  = this.GetKeyInfoHelper(keyType);

            if (helper == null)
            {
                // Cannot detect key type
                return(base.VisitMethodCall(node));
            }

            // Try to parse expression
            MemberInfo[] keyMembers;

            if (!helper.TryParseKeySelectorExpression(
                    secondKeySelector.Body,
                    false,
                    out keyMembers))
            {
                // Cannot parse key
                return(base.VisitMethodCall(node));
            }

            IIndex matchedIndex = null;

            int[] mapping = null;

            foreach (IIndex index in table.Indexes)
            {
                if (KeyExpressionHelper.TryGetMemberMapping(
                        index.KeyInfo.EntityKeyMembers,
                        keyMembers,
                        out mapping))
                {
                    matchedIndex = index;
                    break;
                }
            }

            if (matchedIndex == null)
            {
                // No matched index was found
                return(base.VisitMethodCall(node));
            }

            var indexServices = GetKeyInfoHelper(matchedIndex.KeyInfo);

            if (indexServices == null)
            {
                return(base.VisitMethodCall(node));
            }

            // Create key converter
            ParameterExpression keyConverterParam = Expression.Parameter(keyType, "x");

            LambdaExpression keyConverter =
                Expression.Lambda(
                    KeyExpressionHelper.CreateKeyConversionExpression(keyConverterParam, matchedIndex.KeyInfo.EntityKeyMembers, mapping, helper, indexServices),
                    keyConverterParam);

            // Create key emptyness detector
            ParameterExpression keyEmptinessDetectorParam = Expression.Parameter(keyType, "x");

            LambdaExpression keyEmptinessDetector =
                Expression.Lambda(
                    KeyExpressionHelper.CreateKeyEmptinessDetector(
                        keyEmptinessDetectorParam,
                        helper),
                    keyEmptinessDetectorParam);

            Type[] generics = node.Method.GetGenericArguments();

            // GroupJoinIndexed call
            MethodInfo indexedMethod = this.Indexed
                                       .MakeGenericMethod(
                generics[0],
                generics[1],
                generics[2],
                matchedIndex.KeyInfo.KeyType,
                generics[3]);

            Expression indexedCall =
                Expression.Call(
                    node.Object,
                    indexedMethod,
                    this.Visit(node.Arguments[0]),
                    Expression.Constant(matchedIndex),
                    ExpressionHelper.SkipQuoteNode(node.Arguments[2]),
                    keyEmptinessDetector,
                    keyConverter,
                    ExpressionHelper.SkipQuoteNode(node.Arguments[4]));

            Type elementType = ReflectionHelper.GetElementType(indexedCall.Type);

            // AsQueryable call
            return(Expression.Call(
                       null,
                       QueryMethods.AsQueryable.MakeGenericMethod(elementType),
                       indexedCall));
        }