private static IDbSelectable CreateNewSelectableForWrappingSelect(
            IDbSelect dbSelect, IDbSelectable selectable, DbReference dbRef, Expression m,
            IDbObjectFactory dbFactory, UniqueNameGenerator nameGenerator)
        {
            if (dbRef == null)
            {
                return(selectable);
            }

            var oCol = selectable as IDbColumn;

            if (oCol != null)
            {
                return(dbFactory.BuildColumn(dbRef, oCol.GetAliasOrName(), oCol.ValType));
            }

            var oRefCol = selectable as IDbRefColumn;

            if (oRefCol != null)
            {
                return(dbFactory.BuildRefColumn(dbRef, oRefCol.Alias, oRefCol));
            }

            if (selectable is IDbFunc oDbFunc)
            {
                if (string.IsNullOrEmpty(oDbFunc.Alias))
                {
                    oDbFunc.Alias = nameGenerator.GenerateAlias(dbSelect, oDbFunc.Name, true);
                }

                return(dbFactory.BuildColumn(dbRef, oDbFunc.Alias, oDbFunc.ReturnType));
            }

            return(dbFactory.BuildColumn(dbRef, selectable.Alias, typeof(string)));
        }
        public static IDbSelectable[] ProcessSelection(IDbObject dbObj, IDbObjectFactory factory)
        {
            var dbList = dbObj as IDbList <DbKeyValue>;

            if (dbList != null)
            {
                var keyVals = dbList;
                return(keyVals.SelectMany(kv => ProcessSelection(kv, factory)).ToArray());
            }

            var obj = dbObj as DbReference;

            if (obj != null)
            {
                var dbRef = obj;
                return(new IDbSelectable[] { factory.BuildRefColumn(dbRef, dbRef.RefColumnAlias) });
            }

            var dbBinary = dbObj as IDbBinary;

            if (dbBinary != null && (
                    dbBinary.Operator == DbOperator.Equal ||
                    dbBinary.Operator == DbOperator.NotEqual ||
                    dbBinary.Operator == DbOperator.GreaterThan ||
                    dbBinary.Operator == DbOperator.GreaterThanOrEqual ||
                    dbBinary.Operator == DbOperator.LessThan ||
                    dbBinary.Operator == DbOperator.LessThanOrEqual ||
                    dbBinary.Operator == DbOperator.Is ||
                    dbBinary.Operator == DbOperator.IsNot))
            {
                var dbTrue = factory.BuildConstant(true);
                var tuple  = Tuple.Create <IDbBinary, IDbObject>(dbBinary, dbTrue);
                return(new IDbSelectable[] { factory.BuildCondition(new [] { tuple }, factory.BuildConstant(false)) });
            }

            var keyValue = dbObj as DbKeyValue;

            if (keyValue == null)
            {
                return new[] { (IDbSelectable)dbObj }
            }
            ;

            var selectables = ProcessSelection(keyValue.Value, factory);

            foreach (var selectable in selectables)
            {
                selectable.Alias = keyValue.Key;
            }

            return(selectables);
        }
예제 #3
0
        public static IDbSelectable[] ProcessSelection(IDbObject dbObj, IDbObjectFactory factory)
        {
            switch (dbObj)
            {
            case IDbList <DbKeyValue> dbList:
                var keyVals = dbList;
                return(keyVals.SelectMany(kv => ProcessSelection(kv, factory)).ToArray());

            case DbReference obj:
                var dbRef = obj;
                return(new IDbSelectable[] { factory.BuildRefColumn(dbRef, dbRef.RefColumnAlias) });

            case IDbBinary dbBinary when(
                    dbBinary.Operator == DbOperator.Equal ||
                    dbBinary.Operator == DbOperator.NotEqual ||
                    dbBinary.Operator == DbOperator.GreaterThan ||
                    dbBinary.Operator == DbOperator.GreaterThanOrEqual ||
                    dbBinary.Operator == DbOperator.LessThan ||
                    dbBinary.Operator == DbOperator.LessThanOrEqual ||
                    dbBinary.Operator == DbOperator.Is ||
                    dbBinary.Operator == DbOperator.IsNot):
                var dbTrue = factory.BuildConstant(true);

                var tuple = Tuple.Create <IDbBinary, IDbObject>(dbBinary, dbTrue);
                return(new IDbSelectable[] { factory.BuildCondition(new [] { tuple }, factory.BuildConstant(false)) });
            }

            if (!(dbObj is DbKeyValue keyValue))
            {
                return new[] { (IDbSelectable)dbObj }
            }
            ;

            var selectables = ProcessSelection(keyValue.Value, factory);

            foreach (var selectable in selectables)
            {
                selectable.Alias = keyValue.Key;
            }

            return(selectables);
        }
        private static IDbSelectable CreateNewSelectableForWrappingSelect(
            IDbSelectable selectable, DbReference dbRef, IDbObjectFactory dbFactory)
        {
            if (dbRef == null)
            {
                return(selectable);
            }

            var oCol = selectable as IDbColumn;

            if (oCol != null)
            {
                return(dbFactory.BuildColumn(dbRef, oCol.GetAliasOrName(), oCol.ValType));
            }

            var oRefCol = selectable as IDbRefColumn;

            if (oRefCol != null)
            {
                return(dbFactory.BuildRefColumn(dbRef, oRefCol.Alias, oRefCol));
            }

            return(dbFactory.BuildColumn(dbRef, selectable.Alias, typeof(string)));
        }
예제 #5
0
        protected override Expression VisitMember(MemberExpression m)
        {
            var expression = Visit(m.Expression);

            if (expression is ConstantExpression constExpr)
            {
                var container = constExpr.Value;
                var member    = m.Member;

                object value          = null;
                var    valueRetrieved = false;
                switch (member)
                {
                case FieldInfo field:
                    value          = field.GetValue(container);
                    valueRetrieved = true;
                    break;

                case PropertyInfo prop:
                    value          = prop.GetValue(container, null);
                    valueRetrieved = true;
                    break;
                }

                if (valueRetrieved)
                {
                    var dbObject = _dbFactory.BuildConstant(value, true);
                    _state.ResultStack.Push(dbObject);
                    return(m);
                }
            }

            var typeInfo = m.Type.GetTypeInfo();

            if (m.Expression.Type.IsAnonymouse())
            {
                var dbRef = (DbReference)_state.ResultStack.Peek();
                if (dbRef.RefSelection.ContainsKey(m.Member.Name))
                {
                    var dbObj = dbRef.RefSelection[m.Member.Name];

                    // pop out the dbRef from the stack, it was the result of
                    // translate a parameter, and it is not required for following translation
                    _state.ResultStack.Pop();
                    _state.ResultStack.Push(dbObj);

                    return(m);
                }
            }

            if (m.Expression.Type.IsGrouping())
            {
                var dbRef = (DbReference)_state.ResultStack.Pop();

                var dbSelect = dbRef.OwnerSelect;
                if (dbSelect.GroupBys.IsSingleKey)
                {
                    var kColumn = dbSelect.GroupBys.Single();
                    _state.ResultStack.Push(kColumn);
                }
                else
                {
                    _state.ResultStack.Push(dbRef);
                }

                return(m);
            }

            // if the member is a queryable entity, we need to translate it
            // into a relation, which means a join
            var entityInfo = _infoProvider.FindEntityInfo(m.Type);

            if (entityInfo != null)
            {
                var dbObj   = _state.ResultStack.Pop();
                var refCol  = dbObj as IDbRefColumn;
                var fromRef = refCol != null ? refCol.Ref : (DbReference)dbObj;

                var fromEntity = _infoProvider.FindEntityInfo(m.Expression.Type);
                var relation   = fromEntity.GetRelation(m.Member.Name);

                var dbJoin = GetOrCreateJoin(relation, fromRef, refCol ?? fromRef.ReferredRefColumn);

                // RefColumnAlias is used as alias in case we need to create a ref column for this dbRef
                dbJoin.To.RefColumnAlias = m.Member.Name;

                if (refCol != null)
                {
                    refCol = _dbFactory.BuildRefColumn(dbJoin.To, m.Member.Name);

                    if (dbJoin.To.Referee is IDbSelect subSelect)
                    {
                        refCol.RefTo = subSelect.Selection.OfType <IDbRefColumn>().Single();
                    }

                    _state.ResultStack.Push(refCol);
                    return(m);
                }

                _state.ResultStack.Push(relation.IsChildRelation ? dbJoin.To.Referee : dbJoin.To);
                return(m);
            }

            if (typeInfo.Namespace.StartsWith("System"))
            {
                var dbObj  = _state.ResultStack.Pop();
                var refCol = dbObj as IDbRefColumn;
                var dbRef  = refCol != null ? refCol.Ref : (DbReference)dbObj;

                var fieldInfo = _infoProvider.FindFieldInfo(m.Member);
                var col       = _dbFactory.BuildColumn(dbRef, fieldInfo.DbName, fieldInfo.ValType);
                _state.ResultStack.Push(col);

                // if we create a column whose DbRef is using by a RefColumn
                // we need to make sure the column is added to the ref column's owner select
                // This normally happen when we are accessing a column from a child relation
                refCol = refCol ?? dbRef.ReferredRefColumn;

                // if the ref column is not now, and it is referring another ref column
                // we need to make sure the column we translated is in the sub select which
                // owns the ref column that referred by the current refColumn
                refCol?.RefTo?.AddToReferedSelect(_dbFactory, fieldInfo.DbName, fieldInfo.ValType);

                return(m);
            }

            return(base.VisitMember(m));
        }