/// <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( ); }
/// <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); }