コード例 #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();
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        public static Expression CreateKeyConversionExpression(
            Expression source,
            MemberInfo[] toMembers,
            int[] mapping,
            IKeyInfoHelper from,
            IKeyInfoHelper to)
        {
            int memberCount = mapping.Length;

            Expression[] factoryArgs = new Expression[memberCount];

            for (int i = 0; i < memberCount; i++)
            {
                Type       requestedType = ReflectionHelper.GetMemberType(toMembers[i]);
                Expression arg           = from.CreateKeyMemberSelectorExpression(source, mapping[i]);

                if (arg.Type != requestedType)
                {
                    arg = Expression.Convert(arg, requestedType);
                }

                factoryArgs[i] = arg;
            }

            return(to.CreateKeyFactoryExpression(factoryArgs));
        }
コード例 #4
0
 public KeyInfoBase(
     Expression <Func <TEntity, TKey> > keySelector,
     SortOrder[] sortOrders,
     IComparer <TKey> keyComparer,
     IKeyInfoHelper helper)
     : this(ParseSelector(keySelector, helper), sortOrders, keyComparer, helper)
 {
 }
コード例 #5
0
 private static MemberInfo[] ParseSelector(
     Expression <Func <TEntity, TKey> > selector,
     IKeyInfoHelper helper)
 {
     if (!helper.TryParseKeySelectorExpression(
             selector.Body,
             true,
             out MemberInfo[] result))
コード例 #6
0
        public static Expression <Func <TKey, bool> > CreateKeyEmptinessDetector <TEntity, TKey>(
            IKeyInfoHelper helper)
        {
            ParameterExpression param = Expression.Parameter(typeof(TKey));

            Expression body = CreateKeyEmptinessDetector(param, helper);

            return(Expression.Lambda <Func <TKey, bool> >(body, param));
        }
コード例 #7
0
        public static Expression <Func <TEntity, TKey> > CreateKeySelector <TEntity, TKey>(
            MemberInfo[] entityMembers,
            IKeyInfoHelper helper)
        {
            ParameterExpression param = Expression.Parameter(typeof(TEntity));

            Expression body = CreateKeySelector(param, entityMembers, helper);

            return(Expression.Lambda <Func <TEntity, TKey> >(body, param));
        }
コード例 #8
0
        public bool TryCreateKeyInfoHelper(Type keyType, out IKeyInfoHelper result)
        {
            if (!typeof(DataRow).IsAssignableFrom(keyType))
            {
                result = null;
                return(false);
            }

            result = new DataRowKeyInfoHelper(keyType);
            return(true);
        }
コード例 #9
0
        public bool TryCreateKeyInfoHelper(
            Type keyType,
            out IKeyInfoHelper result)
        {
            if (!ReflectionHelper.IsAnonymousType(keyType))
            {
                result = null;
                return(false);
            }

            result = new AnonymousTypeKeyInfoHelper(keyType);
            return(true);
        }
コード例 #10
0
        public bool TryCreateKeyInfoHelper(
            Type keyType,
            out IKeyInfoHelper result)
        {
            if (!ValidateType(keyType))
            {
                result = null;
                return(false);
            }

            result = new PrimitiveKeyInfoHelper(keyType);
            return(true);
        }
コード例 #11
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))
コード例 #12
0
        public static Expression CreateKeySelector(
            Expression source,
            MemberInfo[] entityMembers,
            IKeyInfoHelper helper)
        {
            Expression[] memberAccess = new Expression[entityMembers.Length];

            for (int i = 0; i < entityMembers.Length; i++)
            {
                memberAccess[i] = Expression.MakeMemberAccess(source, entityMembers[i]);
            }

            Expression body = helper.CreateKeyFactoryExpression(memberAccess);

            return(body);
        }
コード例 #13
0
ファイル: KeyInfoBase.cs プロジェクト: JQ-IOWA/XrmUnitTest
        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);
        }
コード例 #14
0
        public bool TryCreateKeyInfoHelper(
            Type keyType,
            out IKeyInfoHelper result)
        {
            result = null;
            bool success = false;

            foreach (IKeyInfoService factory in this.factories)
            {
                if (factory.TryCreateKeyInfoHelper(keyType, out result))
                {
                    success = true;
                    break;
                }
            }

            return(success);
        }
コード例 #15
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());
        }
コード例 #16
0
        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))
コード例 #17
0
        public static Expression CreateKeyEmptinessDetector(
            Expression source,
            IKeyInfoHelper helper)
        {
            Expression body        = null;
            int        memberCount = helper.GetMemberCount();

            for (int i = 0; i < memberCount; i++)
            {
                Expression member     = helper.CreateKeyMemberSelectorExpression(source, i);
                Type       memberType = member.Type;

                if (ReflectionHelper.IsNullable(memberType))
                {
                    Expression equalityTest =
                        Expression.Equal(
                            member,
                            Expression.Constant(null, memberType));

                    if (body == null)
                    {
                        body = equalityTest;
                    }
                    else
                    {
                        body = Expression.Or(body, equalityTest);
                    }
                }
            }

            // If all the members of the anonymous type is not nullable, the body expression
            // is null at this point
            if (body == null)
            {
                body = Expression.Constant(false);
            }

            return(body);
        }
コード例 #18
0
        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);
        }
コード例 #19
0
        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));
        }
コード例 #20
0
        public GenericKeyComparer(SortOrder[] sortOrders, IKeyInfoHelper helper)
        {
            if (helper == null)
            {
                throw new ArgumentNullException("helper");
            }

            int memberCount = helper.GetMemberCount();

            if (memberCount <= 0)
            {
                throw new ArgumentException(
                          ExceptionMessages.InvalidKeyInfoHelper,
                          "helper");
            }

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

            if (sortOrders.Length != memberCount)
            {
                throw new ArgumentException(
                          ExceptionMessages.MemberAndSortOrderCountMismatch,
                          "sortOrders");
            }

            ParameterExpression x = Expression.Parameter(typeof(T), "x");
            ParameterExpression y = Expression.Parameter(typeof(T), "y");

            ParameterExpression variable = Expression.Variable(typeof(int), "var");

            List <Expression> blockBody = new List <Expression>();

            for (int i = 0; i < memberCount; i++)
            {
                Expression xMember = helper.CreateKeyMemberSelectorExpression(x, i);
                Expression yMember = helper.CreateKeyMemberSelectorExpression(y, i);

                Expression expr =
                    Expression.Assign(
                        variable,
                        this.CreateComparsion(xMember, yMember, sortOrders[i]));

                if (0 < i)
                {
                    expr =
                        Expression.IfThen(
                            Expression.Equal(variable, Expression.Constant(0)),
                            expr);
                }

                blockBody.Add(expr);
            }

            // Eval the last variable
            blockBody.Add(variable);

            var lambda = Expression.Lambda <Func <T, T, int> >(
                Expression.Block(
                    new ParameterExpression[] { variable },
                    blockBody),
                x,
                y);

            this.comparer = lambda.Compile();
        }