public bool TryCreateKeyInfo <TEntity, TKey>(
            Expression <Func <TEntity, TKey> > keySelector,
            out IKeyInfo <TEntity, TKey> result)
            where TEntity : class
        {
            Expression body    = keySelector.Body;
            Type       keyType = body.Type;

            if (!typeof(DataRow).IsAssignableFrom(body.Type))
            {
                result = null;
                return(false);
            }

            IKeyInfoHelper helper = DataRowKeyInfo <TEntity, TKey> .KeyInfoHelper;

            MemberInfo[] keyMembers;
            if (!helper.TryParseKeySelectorExpression(keySelector.Body, true, out keyMembers))
            {
                result = null;
                return(false);
            }

            result = new DataRowKeyInfo <TEntity, TKey>(keyMembers);
            return(true);
        }
Esempio n. 2
0
 private static MemberInfo[] ParseSelector(
     Expression <Func <TEntity, TKey> > selector,
     IKeyInfoHelper helper)
 {
     if (!helper.TryParseKeySelectorExpression(
             selector.Body,
             true,
             out MemberInfo[] result))
Esempio n. 3
0
        public bool TryCreateKeyInfo <TEntity, TKey>(
            Expression <Func <TEntity, TKey> > keySelector,
            out IKeyInfo <TEntity, TKey> result) where TEntity : class
        {
            if (!ValidateType(typeof(TKey)))
            {
                result = null;
                return(false);
            }

            IKeyInfoHelper helper = PrimitiveKeyInfo <TEntity, TKey> .KeyInfoHelper;


            if (!helper.TryParseKeySelectorExpression(keySelector.Body, true, out MemberInfo[] members))
Esempio n. 4
0
        private static MemberInfo[] ParseSelector(
            Expression <Func <TEntity, TKey> > selector,
            IKeyInfoHelper helper)
        {
            MemberInfo[] result = null;

            if (!helper.TryParseKeySelectorExpression(
                    selector.Body,
                    true,
                    out result))
            {
                throw new ArgumentException(
                          ExceptionMessages.InvalidKeySelector,
                          "keySelector");
            }

            return(result);
        }
        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            if (!node.Method.IsGenericMethod ||
                node.Method.GetGenericMethodDefinition() != this.Original)
            {
                // Not GroupJoin
                return(base.VisitMethodCall(node));
            }


            if (!(node.Arguments[1] is ConstantExpression secondExpression))
            {
                // Not constant expression
                return(base.VisitMethodCall(node));
            }


            if (!(secondExpression.Value is ITable table))
            {
                // 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

            if (!helper.TryParseKeySelectorExpression(
                    secondKeySelector.Body,
                    false,
                    out MemberInfo[] keyMembers))
        public bool TryCreateKeyInfo <TEntity, TKey>(
            Expression <Func <TEntity, TKey> > keySelector,
            out IKeyInfo <TEntity, TKey> result) where TEntity : class
        {
            if (!ReflectionHelper.IsAnonymousType(typeof(TKey)))
            {
                result = null;
                return(false);
            }

            IKeyInfoHelper helper = AnonymousTypeKeyInfo <TEntity, TKey> .KeyInfoHelper;

            MemberInfo[] members;

            if (!helper.TryParseKeySelectorExpression(keySelector.Body, true, out members))
            {
                result = null;
                return(false);
            }

            result = new AnonymousTypeKeyInfo <TEntity, TKey>(members);
            return(true);
        }
        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));
        }