Ejemplo n.º 1
0
        public void Run()
        {
            /*
             * TODO: account for scope when subquery is implemented
             * Note: aliases have scope. Alias in subquery can override alias from the outer one.
             * Also alias can not be visible from sibling subqueries.
             */

            //
            // Build alias map
            //
            var dataSources  = new GraphIterator<INode>(TranslationContext.Instance.Batch, node => node.Children).
                DepthFirst().
                OfType<DataSourceNode>();

            var aliasMap = new Dictionary<string,DataSourceNode>(StringComparer.OrdinalIgnoreCase);
            foreach(var ds in dataSources)
                if(aliasMap.ContainsKey(ds.Alias))
                    throw new ApplicationException("Alias '"+ds.Alias+"' is declared twice");
                else
                    aliasMap.Add(ds.Alias, ds);

            //
            new GraphIterator<INode>(TranslationContext.Instance.Batch, n => n.Children).
                DepthFirst().
                OfType<ColumnExpressionNode>().
                ForEach(c => {
                        DataSourceNode dataSource;
                        if(!aliasMap.TryGetValue(c.TableAlias, out dataSource))
                            throw new UnresolvedAliasException(c);
                        c.AliasReference = dataSource;
                });

            // fire binding events
            foreach(var p in aliasMap)
                if(TranslationContext.Instance.OnTableAliasBound != null)
                    TranslationContext.Instance.OnTableAliasBound(p.Key, p.Value);
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     <para>
        ///         Begins tracking an entity and any entities that are reachable by traversing it's navigation properties.
        ///         Traversal is recursive so the navigation properties of any discovered entities will also be scanned.
        ///         The specified <paramref name="callback" /> is called for each discovered entity and must set the
        ///         <see cref="EntityEntry.State" /> that each entity should be tracked in. If no state is set, the entity
        ///         remains untracked.
        ///     </para>
        ///     <para>
        ///         This method is designed for use in disconnected scenarios where entities are retrieved using one instance of
        ///         the context and then changes are saved using a different instance of the context. An example of this is a
        ///         web service where one service call retrieves entities from the database and another service call persists
        ///         any changes to the entities. Each service call uses a new instance of the context that is disposed when the
        ///         call is complete.
        ///     </para>
        ///     <para>
        ///         If an entity is discovered that is already tracked by the context, that entity is not processed (and it's
        ///         navigation properties are not traversed).
        ///     </para>
        /// </summary>
        /// <param name="rootEntity"> The entity to begin traversal from. </param>
        /// <param name="callback">
        ///     An action to configure the change tracking information for each entity. For the entity to begin being tracked,
        ///     the <see cref="EntityEntry.State" /> must be set.
        /// </param>
        public virtual void TrackGraph(
            [NotNull] object rootEntity,
            [NotNull] Action <EntityEntryGraphNode> callback)
        {
            Check.NotNull(rootEntity, nameof(rootEntity));
            Check.NotNull(callback, nameof(callback));

            var rootEntry = StateManager.GetOrCreateEntry(rootEntity);

            GraphIterator.TraverseGraph(
                new EntityEntryGraphNode(rootEntry, null, null),
                n =>
            {
                if (n.Entry.State != EntityState.Detached)
                {
                    return(false);
                }

                callback(n);

                return(n.Entry.State != EntityState.Detached);
            });
        }
Ejemplo n.º 3
0
        public void Run()
        {
            var classTables = new GraphIterator<INode>(TranslationContext.Instance.Batch, n => n.Children).
                BreadthFirst().
                OfType<TableNode>().
                Where(t => t.Name.Equals("class", StringComparison.InvariantCultureIgnoreCase));

            foreach(var table in classTables)
                HandleClass(table);
        }