private Expression MakeSimpleCondition(FieldCondition fieldCondition)
        {
            PropertyInfo leftPropertyInfo = fieldCondition.LeftElementType.GetProperty(fieldCondition.LeftFieldName);
            if (leftPropertyInfo == null)
            {
                throw new SpoltyException("Left field not found");
            }

            PropertyInfo rightPropertyInfo = fieldCondition.RightElementType.GetProperty(fieldCondition.RightFieldName);
            if (rightPropertyInfo == null)
            {
                throw new SpoltyException("Right field not found");
            }

            ParameterExpression leftParam =
                ExpressionHelper.CreateOrGetParameterExpression(fieldCondition.LeftElementType, fieldCondition.LeftElementType.Name, Factory.Store);
            ParameterExpression rightParam =
                ExpressionHelper.CreateOrGetParameterExpression(fieldCondition.RightElementType, fieldCondition.RightElementType.Name, Factory.Store);

            Expression leftExpression =
                ExpressionHelper.CreateMemberExpression(fieldCondition.LeftElementType, fieldCondition.LeftFieldName, leftParam);
            Expression rightExpression =
                ExpressionHelper.CreateMemberExpression(fieldCondition.RightElementType, fieldCondition.RightFieldName, rightParam);

            rightExpression =
                ExpressionHelper.ConvertOrCastInnerPropertyExpression(leftPropertyInfo.PropertyType, rightPropertyInfo, rightExpression);

            Expression body = MakeComparisonExpression(leftExpression, rightExpression, fieldCondition.Operator);
            return body;
        }
        private Expression MakeInnerJoin(Expression outerExpression, Expression innerExpression,
            string[] leftFieldsNames, string[] rightFieldsNames,
            ConditionList conditions)
        {
            Checker.CheckArgumentNull(outerExpression, "outerExpression");
            Checker.CheckArgumentNull(innerExpression, "innerExpression");
            Checker.CheckArgumentNull(leftFieldsNames, "leftFieldsNames");
            Checker.CheckArgumentNull(outerExpression, "outerExpression");

            int fieldsCount = leftFieldsNames.Length;
            if (fieldsCount != rightFieldsNames.Length)
            {
                throw new SpoltyException("Number of fields mismatch");
            }

            Type outerType = ExpressionHelper.GetGenericType(outerExpression);
            ParameterExpression outerParam = ExpressionHelper.CreateOrGetParameterExpression(outerType, outerType.Name, Factory.Store);
            Type innerType = ExpressionHelper.GetGenericType(innerExpression);
            ParameterExpression innerParam = ExpressionHelper.CreateOrGetParameterExpression(innerType, innerType.Name, Factory.Store);

            var clw = new ConditionList();

            for (int index = 1; index < fieldsCount; index++)
            {
                var fieldCondition =
                    new FieldCondition(leftFieldsNames[index],
                                       ConditionOperator.EqualTo, rightFieldsNames[index], outerType, innerType);
                clw.Add(fieldCondition);
            }

            PropertyInfo outerPropertyInfo = outerType.GetProperty(leftFieldsNames[0]);
            if (outerPropertyInfo == null)
            {
                throw new SpoltyException("Property not found");
            }
            PropertyInfo innerPropertyInfo = innerType.GetProperty(rightFieldsNames[0]);
            if (innerPropertyInfo == null)
            {
                throw new SpoltyException("Property not found");
            }

            Expression outerPropertyExpression = Expression.Property(outerParam, outerPropertyInfo);
            Expression innerPropertyExpression = Expression.Property(innerParam, innerPropertyInfo);

            Type type = outerPropertyInfo.PropertyType;
            innerPropertyExpression =
                ExpressionHelper.ConvertOrCastInnerPropertyExpression(type, innerPropertyInfo, innerPropertyExpression);

            LambdaExpression outerKeySelector = Expression.Lambda(outerPropertyExpression, outerParam);
            LambdaExpression innerKeySelector = Expression.Lambda(innerPropertyExpression, innerParam);
            LambdaExpression resultSelector = Expression.Lambda(outerParam, outerParam, innerParam);

            if (conditions != null && conditions.Count > 0)
            {
                clw.AddConditions(conditions);
            }

            Expression resultJoinExpression = CallJoinMethod(outerExpression, innerExpression, outerKeySelector,
                                                             innerKeySelector,
                                                             resultSelector);
            resultJoinExpression = Factory.CreateConditionExpressionMaker().Make(clw, resultJoinExpression);
            return resultJoinExpression;
        }