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)));
        }
Beispiel #2
0
        private void UpdateSelection(IDbSelect fromSelect, IDbObject selection, DbReference toSelectRef)
        {
            var dbList = selection as IEnumerable <DbKeyValue>;

            if (dbList != null)
            {
                foreach (var dbObj in dbList)
                {
                    UpdateSelection(fromSelect, dbObj, toSelectRef);
                }
                return;
            }

            var keyValue = selection as DbKeyValue;

            selection = keyValue != null ? keyValue.Value : selection;

            var selectable = GetSelectable(fromSelect, selection, toSelectRef);

            if (keyValue != null)
            {
                selectable.Alias = keyValue.Key;
            }

            fromSelect.Selection.Add(selectable);
        }
Beispiel #3
0
        public void DbRefMapsToOtherDocumentsByOid()
        {
            const string databaseName = "NormTests";
            var id = ObjectId.NewObjectId();

            using (var session = new Session())
            {
                session.Drop<Product>();
                session.Drop<ProductReference>();

                session.Add(new Product { _id = id, Name = "RefProduct" });

                var productReference = new DbReference<Product>(id);

                session.Add(new ProductReference
                    {
                        Id = ObjectId.NewObjectId(),
                        Name = "FullCart",
                        ProductsOrdered = new[] { productReference }
                    });
            }

            var server = Mongo.Create("mongodb://localhost/" + databaseName);
            var reference = server.GetCollection<ProductReference>().Find().First();
            var product = reference.ProductsOrdered[0].Fetch(() => server);

            Assert.Equal(id.Value, product._id.Value);
        }
 public virtual IDbSelectable BuildSelectable(DbReference dbRef, string alias = null)
 {
     return(new SqlSelectable
     {
         Ref = dbRef,
         Alias = alias,
         OutputOption = OutputOption
     });
 }
        public IDbSelect BuildSelect(DbReference dbReference)
        {
            var dbSelect = new SqlSelect
            {
                From = dbReference
            };

            dbReference.OwnerSelect = dbSelect;
            return(dbSelect);
        }
Beispiel #6
0
        private Expression VisitParameterInteral(ParameterExpression p, bool ignoreParamStack)
        {
            DbReference dbRef = null;

            if (p.Type.IsAnonymouse() || p.Type.IsGrouping())
            {
                var dbSelect = _state.GetLastSelect();
                dbRef             = _dbFactory.BuildRef(null);
                dbRef.OwnerSelect = dbSelect;

                var collection = p.Type.IsGrouping()
                    ? dbSelect.GroupBys.AsEnumerable()
                    : dbSelect.Selection;

                foreach (var selectable in collection)
                {
                    dbRef.RefSelection[selectable.GetAliasOrName()] = selectable;
                }
            }


            if (dbRef == null && !ignoreParamStack && _state.ParamterStack.Count > 0)
            {
                var dbRefs = _state.ParamterStack.Peek();
                if (dbRefs.ContainsKey(p))
                {
                    dbRef = dbRefs[p];
                }
            }

            // if we can not find the parameter expression in the ParamterStack,
            // it means this is the first time we translates the parameter, so we
            // need to look for it in the most recently translated select
            // this is required because we may not always has select on the top
            // of the stack, especially we translating arguments for method calls
            if (dbRef == null)
            {
                var dbSelect = _state.GetLastSelect();

                var refCol = (_state.ResultStack.Peek() as IDbRefColumn) ??
                             dbSelect.Selection.OfType <IDbRefColumn>().LastOrDefault();

                dbRef = refCol != null ? refCol.Ref : dbSelect.From;
            }

            if (dbRef == null)
            {
                throw new NullReferenceException();
            }

            _state.ResultStack.Push(dbRef);

            return(p);
        }
 public virtual IDbColumn BuildColumn(
     DbReference dbRef, string colName, DbValType type, string alias = null, bool isJoinKey = false)
 {
     return(new SqlColumn
     {
         Name = colName,
         Ref = dbRef,
         ValType = type,
         Alias = alias,
         IsJoinKey = isJoinKey,
         OutputOption = OutputOption
     });
 }
        public IDbRefColumn BuildRefColumn(DbReference dbRef, string alias = null, IDbRefColumn fromRefColumn = null)
        {
            var refCol = new SqlRefColumn
            {
                Ref   = dbRef,
                Alias = alias,
                RefTo = fromRefColumn
            };

            if (dbRef != null)
            {
                dbRef.ReferredRefColumn = refCol;
            }

            return(refCol);
        }
        public IDbJoin BuildJoin(
            DbReference joinTo, IDbSelect dbSelect, IDbBinary condition = null,
            DbJoinType dbJoinType = DbJoinType.Inner)
        {
            var dbJoin = new SqlJoin
            {
                To        = joinTo,
                Condition = condition,
                Type      = dbJoinType
            };

            joinTo.OwnerSelect = dbSelect;
            joinTo.OwnerJoin   = dbJoin;

            return(dbJoin);
        }
Beispiel #10
0
        /// update all joins that are related to dbRef to be left outer join
        /// this is required by method such as Select or GroupBy
        public static void UpdateJoinType(DbReference dbRef, DbJoinType dbJoinType = DbJoinType.LeftOuter)
        {
            var joins = dbRef?.OwnerSelect?.Joins.Where(j => ReferenceEquals(j.To, dbRef));

            if (joins == null)
            {
                return;
            }

            foreach (var dbJoin in joins)
            {
                dbJoin.Type = dbJoinType;
                var relatedRefs = dbJoin.Condition.GetOperands().
                                  Select(op => (op as IDbSelectable)?.Ref).
                                  Where(r => r != null && !ReferenceEquals(r, dbJoin.To));

                foreach (var relatedRef in relatedRefs)
                {
                    UpdateJoinType(relatedRef);
                }
            }
        }
Beispiel #11
0
        private IDbSelectable GetSelectable(IDbSelect fromSelect, IDbObject selection, DbReference toSelectRef)
        {
            var dbRef = selection as DbReference;

            if (dbRef != null)
            {
                IDbRefColumn toRefCol = null;
                if (dbRef.OwnerSelect != fromSelect)
                {
                    var toSelect = (IDbSelect)toSelectRef.Referee;
                    toRefCol = _dbFactory.BuildRefColumn(dbRef);

                    toSelect.Selection.Add(toRefCol);
                    dbRef = toSelectRef;
                }

                var refColumn = _dbFactory.BuildRefColumn(dbRef);
                refColumn.RefTo = toRefCol;
                return(refColumn);
            }

            var column = selection as IDbColumn;

            if (column != null)
            {
                if (column.Ref.OwnerSelect != fromSelect)
                {
                    var toSelect = (IDbSelect)toSelectRef.Referee;
                    toSelect.Selection.Add(column);

                    column     = _dbFactory.BuildColumn(column);
                    column.Ref = toSelectRef;
                }

                return(column);
            }

            throw new NotSupportedException();
        }
Beispiel #12
0
        public void DbRefMapsToOtherDocumentsByOid()
        {
            var id = ObjectId.NewObjectId();

            using (var db = Mongo.Create(TestHelper.ConnectionString()))
            {

                db.GetCollection<TestProduct>().Insert(new TestProduct { _id = id, Name = "RefProduct" });

                var productReference = new DbReference<TestProduct>(id);

                db.GetCollection<ProductReference>().Insert(new ProductReference
                    {
                        Id = ObjectId.NewObjectId(),
                        Name = "FullCart",
                        ProductsOrdered = new[] { productReference }
                    });

                var reference = db.GetCollection<ProductReference>().Find(new { }).First();
                var product = reference.ProductsOrdered[0].Fetch(() => db);
                Assert.Equal(id.Value, product._id.Value);
            }
        }
        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)));
        }
Beispiel #14
0
        public void DbRefMapsToOtherDocumentsByOid()
        {
            var id = ObjectId.NewObjectId();

            using (var db = Mongo.Create(TestHelper.ConnectionString()))
            {
                db.GetCollection <TestProduct>().Insert(new TestProduct {
                    _id = id, Name = "RefProduct"
                });

                var productReference = new DbReference <TestProduct>(id);

                db.GetCollection <ProductReference>().Insert(new ProductReference
                {
                    Id              = ObjectId.NewObjectId(),
                    Name            = "FullCart",
                    ProductsOrdered = new[] { productReference }
                });

                var reference = db.GetCollection <ProductReference>().Find(new { }).First();
                var product   = reference.ProductsOrdered[0].Fetch(() => db);
                Assert.Equal(id.Value, product._id.Value);
            }
        }
Beispiel #15
0
        /// Create a join for the relation
        /// For parent relation, we create a join that joins to the parent table
        /// For child relation, we will create a sub select that returns the child table,
        /// and then joins to the sub select.
        /// The reason for joining to sub select for child relation, is that we want to be
        /// able to group on the join key, so that we will not repeat the parent row.
        private IDbJoin GetOrCreateJoin(EntityRelation relation, DbReference fromRef, IDbRefColumn refCol)
        {
            var dbSelect = fromRef.OwnerSelect;
            var tupleKey = Tuple.Create(dbSelect, relation);

            if (!relation.IsChildRelation && _state.CreatedJoins.ContainsKey(tupleKey))
            {
                return(_state.CreatedJoins[tupleKey]);
            }

            var toEntity = relation.ToEntity;
            var dbTable  = _dbFactory.BuildTable(toEntity);

            DbReference joinTo;
            DbReference childRef    = null;
            IDbSelect   childSelect = null;

            // Create the join. For parent join, we just need to join to a Ref to the table
            // For child relation, we will firstly create a sub select that return the child table
            // and then join to then sub select
            if (!relation.IsChildRelation)
            {
                var tableAlias = _nameGenerator.GenerateAlias(dbSelect, dbTable.TableName);
                joinTo = _dbFactory.BuildRef(dbTable, tableAlias);
            }
            else
            {
                childRef       = _dbFactory.BuildRef(dbTable);
                childSelect    = _dbFactory.BuildSelect(childRef);
                childRef.Alias = _nameGenerator.GenerateAlias(childSelect, dbTable.TableName);

                var tableAlias = _nameGenerator.GenerateAlias(dbSelect, TranslationConstants.SubSelectPrefix, true);
                joinTo = _dbFactory.BuildRef(childSelect, tableAlias);
            }

            var dbJoin = _dbFactory.BuildJoin(joinTo, dbSelect);

            dbSelect.Joins.Add(dbJoin);

            // build join condition
            IDbBinary condition = null;

            for (var i = 0; i < relation.FromKeys.Count; i++)
            {
                var fromKey = relation.FromKeys[i];
                var toKey   = relation.ToKeys[i];

                var fromColumn = _dbFactory.BuildColumn(fromRef, fromKey.DbName, fromKey.ValType);
                var toColumn   = _dbFactory.BuildColumn(joinTo, toKey.DbName, toKey.ValType);

                // If we have created a sub for child relation, we need to the columns
                // that are used in join condition selected from the sub select.
                if (childRef != null && childSelect != null)
                {
                    var alias       = _nameGenerator.GenerateAlias(childSelect, toKey.DbName + TranslationConstants.JoinKeySuffix, true);
                    var childColumn = _dbFactory.BuildColumn(childRef, toKey.DbName, toKey.ValType, alias, true);

                    /**
                     * We need to also put the join key in the group of the sub select.
                     * This is to make sure the sub select is grouped by the key so that
                     * the parent (outer select) will not be repeated
                     * This operation needs to happen here not in the aggregation method call.
                     * The reason is that in aggregtion method calls we do not know which column
                     * from the entity is used in relation, so they will not be able to create
                     * the correct column
                     */
                    childSelect.Selection.Add(_dbFactory.BuildRefColumn(childRef));
                    childSelect.Selection.Add(childColumn);
                    childSelect.GroupBys.Add(childColumn);

                    toColumn.Name  = alias;
                    toColumn.Alias = string.Empty;
                }

                // if the relation is found on a fromRef which is referring a sub-select,
                // it means the from key of the join is not on a table but a derived select.
                // In this case, we need to add the from key into the derived select, as we will
                // be using it in the join
                if (fromRef.Referee is IDbSelect)
                {
                    var alias = _nameGenerator.GenerateAlias(dbSelect, toKey.DbName + TranslationConstants.JoinKeySuffix, true);
                    fromColumn.Name  = alias;
                    fromColumn.Alias = string.Empty;

                    // try to recursively add the join key to all connected sub select.
                    refCol.RefTo?.AddToReferedSelect(_dbFactory, fromKey.DbName, fromKey.ValType, alias);
                }

                var binary = _dbFactory.BuildBinary(fromColumn, DbOperator.Equal, toColumn);
                condition = condition.UpdateBinary(binary, _dbFactory);
            }

            dbJoin.Condition = condition;

            // all relations need to follow the join type
            if (fromRef.OwnerJoin != null)
            {
                dbJoin.Type = fromRef.OwnerJoin.Type;
            }

            if (relation.IsChildRelation)
            {
                dbJoin.Type = DbJoinType.LeftOuter;
            }

            return(_state.CreatedJoins[tupleKey] = dbJoin);
        }
 public IDbColumn BuildColumn(
     DbReference dbRef, string colName, Type type, string alias = null, bool isJoinKey = false)
 {
     return(BuildColumn(dbRef, colName, BuildType(type), alias, isJoinKey));
 }