internal async Task ReadVertexStateAsync(GrainReference grainReference, VertexState vertexState) { var readExpression = $"g.V('{grainReference.ToKeyString()}')"; var graphElementGrain = grainReference.AsReference <IGraphElementGrain>(); var feedOptions = new FeedOptions { MaxItemCount = 1, PartitionKey = new PartitionKey(graphElementGrain.GetGraphPartition()) }; var readQuery = client.CreateGremlinQuery <CosmosDbVertex>(graph, readExpression, feedOptions, GraphSONMode.Normal); var response = await readQuery.ExecuteNextAsync <CosmosDbVertex>(); log.Info($"CosmosDB: Read Vertex State: Request Charge: {response.RequestCharge}"); var vertex = response.FirstOrDefault(); if (vertex == null) { return; } vertexState.Persisted = true; foreach (var edge in vertex.GetInEdges()) { var edgeReference = grainReferenceConverter.GetGrainFromKeyString(edge.Id.ToString()); edgeReference.BindGrainReference(grainFactory); var vertexReference = grainReferenceConverter.GetGrainFromKeyString(edge.InVertexId.ToString()); vertexReference.BindGrainReference(grainFactory); vertexState.AddInEdge(edgeReference.AsReference <IEdge>(), vertexReference.AsReference <IVertex>()); } foreach (var edge in vertex.GetOutEdges()) { var edgeReference = grainReferenceConverter.GetGrainFromKeyString(edge.Id.ToString()); edgeReference.BindGrainReference(grainFactory); var vertexReference = grainReferenceConverter.GetGrainFromKeyString(edge.InVertexId.ToString()); vertexReference.BindGrainReference(grainFactory); vertexState.AddOutEdge(edgeReference.AsReference <IEdge>(), vertexReference.AsReference <IVertex>()); } foreach (var property in vertex.GetVertexProperties()) { if (property.Key[0] == '@' || property.Key == "partition") { continue; } var vertexProperty = vertexState.SetProperty(property.Key, property.Value.ToString()); try { foreach (var subProperty in property.GetProperties()) { if (subProperty.Key[0] == '@') { continue; } vertexProperty.SetMeta(subProperty.Key, subProperty.Value.ToString()); } } // BUG: The Microsoft.Azure.Graphs library throws an exception when enumerating over empty properties. How do we check or work around this? catch (NullReferenceException) { } } }