/// <summary>
        /// Implementation for building the overall T-SQL query.
        /// </summary>
        private void BuildSql( )
        {
            _result = new BulkSqlQuery
            {
                Request = _request
            };

            // Walk the request object graph to get individual nodes
            var allRequestNodes = Delegates.WalkGraph(_request, rq => rq.Relationships.Select(r => r.RequestedMembers));

            // Build info for each node
            int nextTag = 0;

            foreach (EntityMemberRequest node in allRequestNodes)
            {
                var nodeInfo = new RequestNodeInfo
                {
                    Request = node,
                    Tag     = nextTag++
                };
                _requestNodeMap.Add(node, nodeInfo);
                _result.RequestNodes.Add(nodeInfo.Tag, nodeInfo);
            }

            ProcessRelationships( );
            ProcessFields( );
        }
Beispiel #2
0
        /// <summary>
        /// Read relationships, and top level entities, from the database result.
        /// </summary>
        private static void ReadRelationships(IDataReader reader, BulkSqlQuery query, BulkRequestResult result)
        {
            // select distinct EntityId, RelSrcId, RelTypeId from #process
            while (reader.Read())
            {
                // Caution: We're in a database-read context, so don't touch the entity model or things will crash.

                long toId          = reader.GetInt64(0);
                int  nodeTag       = reader.GetInt32(1);    // tag of the request node that returned this entity
                long fromId        = reader.GetInt64(2);    // zero for root-level entities
                long typeIdWithNeg = reader.GetInt64(3);    // relationship type-id, with reverse being indicated with negative values

                // Root result entity
                if (fromId == 0)
                {
                    result.RootEntities.Add(toId);
                }
                else
                {
                    // Add to dictionary
                    var key   = new RelationshipKey(fromId, typeIdWithNeg);
                    var value = toId;

                    List <long> list;
                    if (!result.Relationships.TryGetValue(key, out list))
                    {
                        list = new List <long>();
                        result.Relationships[key] = list;
                    }
                    list.Add(value);
                }

                // Implicit relationship security
                bool implicitlySecured = false;
                if (fromId != 0)
                {
                    var relInfo = query.Relationships[typeIdWithNeg];
                    implicitlySecured = relInfo.ImpliesSecurity;
                }

                // Store entity
                EntityValue ev;
                if (!result.AllEntities.TryGetValue(toId, out ev))
                {
                    ev = new EntityValue {
                        ImplicitlySecured = implicitlySecured
                    };
                    result.AllEntities[toId] = ev;
                }
                else
                {
                    ev.ImplicitlySecured = ev.ImplicitlySecured && implicitlySecured;
                }

                // Store the request node that specified members to load for this entity
                RequestNodeInfo requestNode = query.RequestNodes [nodeTag];
                ev.Nodes.Add(requestNode);
            }

#if DEBUG
            if (result.RootEntitiesList.Count != 0)
            {
                throw new InvalidOperationException("Assert false .. expected RootEntityList to be empty.");
            }
#endif
            result.RootEntitiesList.AddRange(result.RootEntities);

            RemoveDuplicateRelationshipEntries(result);
        }