public override void Translate(
            MethodCallExpression m, TranslationState state, UniqueNameGenerator nameGenerator)
        {
            var dbSelect = state.ResultStack.Peek() as IDbSelect;

            if (dbSelect != null)
            {
                dbSelect.Selection.IsDistinct = true;
            }

            var caller     = m.GetCaller();
            var entityInfo = caller.NodeType == ExpressionType.MemberAccess
                ? this._infoProvider.FindEntityInfo(caller.Type)
                : null;

            // if the caller of the Distinct function is a Entity
            // We need to add its primary keys into the query so that the result
            // of distinct is correct. Otherwise, it will only distinct on join keys
            if (entityInfo != null)
            {
                foreach (var pk in entityInfo.Keys)
                {
                    var pkColumn = _dbFactory.BuildColumn(dbSelect.GetReturnEntityRef(), pk.DbName, pk.ValType);
                    dbSelect.Selection.Add(pkColumn);
                }
            }
        }
Beispiel #2
0
        /// <summary> Translate to SQL </summary>
        public override void Translate(
            MethodCallExpression m, TranslationState state, UniqueNameGenerator nameGenerator)
        {
            var dbExpression = GetAggregationTarget(m, state);

            IDbSelect childSelect = null;

            if (!m.GetCaller().Type.IsGrouping())
            {
                childSelect = state.ResultStack.Pop() as IDbSelect;
            }

            // if the aggregation does not have expression, it means
            // the caller of the aggregation method must be a Select method call
            // In this case, the actual expression that we need to aggregate on,
            // will be inside the child select statement
            if (dbExpression == null && childSelect != null)
            {
                // to get the actual expression, we need to first unwrap the child select
                // because the translation of Select call always wrap the actual select
                childSelect = (IDbSelect)childSelect.From.Referee;

                dbExpression = childSelect.Selection.Last(
                    s => string.IsNullOrEmpty(s.Alias) ||
                    !s.Alias.EndsWith(TranslationConstants.JoinKeySuffix));

                childSelect.Selection.Remove(dbExpression);
                childSelect.GroupBys.Remove(dbExpression);
            }

            if (dbExpression == null)
            {
                throw new NotSupportedException("Can not aggregate.");
            }

            if (!(dbExpression is IDistinctable))
            {
                throw new NotSupportedException("Expression must be Distinctable");
            }

            var distinctable = (IDistinctable)dbExpression;

            distinctable.IsDistinct = true;

            var dbFunc = _dbFactory.BuildFunc("count", true, m.Method.ReturnType, dbExpression);

            CreateAggregation(m, state, nameGenerator, childSelect, dbFunc);
        }
Beispiel #3
0
        public override void Translate(
            MethodCallExpression m, TranslationState state, UniqueNameGenerator nameGenerator)
        {
            var predicate = BuildCondition(m, state);

            IDbSelect childSelect = null;

            if (!m.GetCaller().Type.IsGrouping())
            {
                childSelect = state.ResultStack.Pop() as IDbSelect;
            }

            var dbCountFunc = _dbFactory.BuildFunc(m.Method.Name.ToLower(), true, m.Method.ReturnType, predicate);

            CreateAggregation(m, state, nameGenerator, childSelect, dbCountFunc);
        }
Beispiel #4
0
        protected override Expression VisitMethodCall(MethodCallExpression m)
        {
            var caller = m.GetCaller();
            var args   = m.GetArguments();

            Visit(caller);

            // remove unneed DbReference from stack, this is a side effect of translation of the caller
            // we need to translate the caller to have the required select on the stack
            // but we dont neeed other thing that come with it, such as the DbReference
            while (_state.ResultStack.Count > 0 && _state.ResultStack.Peek() is DbReference)
            {
                _state.ResultStack.Pop();
            }

            VistMethodArguments(args);

            if (!_plugIns.TranslateMethodCall(m, _state, _nameGenerator))
            {
                throw new NotSupportedException();
            }

            return(m);
        }
Beispiel #5
0
        public static Expression[] GetArguments(this MethodCallExpression m)
        {
            var caller = m.GetCaller();

            return(m.Arguments.Where(a => a != caller).ToArray());
        }