2016-06-23 8 views
0

Meine gespeicherten Prozedur: (Ich habe es über Azure Script Explorer)Documentdb fehlgeschlagen gespeicherte Prozedur Antwort auf deserialisieren oder wandeln sie in meinem definierten Typ

function GetAllResources() { 
var collection = getContext().getCollection(); 

// Query documents and take 1st item. 
var isAccepted = collection.queryDocuments(
    collection.getSelfLink(), 
    'SELECT * FROM MultiLanguage as m', 
    function (err, docs, options) { 
     if (err) throw err; 

     // Check the feed and if empty, set the body to 'no docs found', 
     // else take 1st element from feed 
     if (!docs || !docs.length) getContext().getResponse().setBody('no docs found'); 
     else getContext().getResponse().setBody(JSON.stringify(docs)); 
    }); 

    if (!isAccepted) throw new Error('The query was not accepted by the server.'); 
} 

Die sproc erfolgreich aus Skript-Explorer ausgeführt werden.

Mein C# -Code die sproc nennen:

public async Task<IHttpActionResult> GetReources() { 
     client = new DocumentClient(new Uri(ConfigurationManager.AppSettings["endpoint"]), ConfigurationManager.AppSettings["authKey"]); 
     var collectionLink = UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId); 

     //var docs = await client.ReadDocumentFeedAsync(collectionLink, new FeedOptions { MaxItemCount = 10 }); 


     //var docs = from d in client.CreateDocumentQuery<Models.Resource>(collectionLink) 
     //   select d; 

     StoredProcedure storedProcedure = client.CreateStoredProcedureQuery(collectionLink).Where(c => c.Id == "GetAllResources").AsEnumerable().FirstOrDefault(); 

     Models.Resource docs = await client.ExecuteStoredProcedureAsync<Models.Resource>(storedProcedure.SelfLink); 


     foreach (var d in docs) { 
      Models.Resource a = new Models.Resource(); 
      a = docs; 
      //a.id = d.id; 
      //a.Scenario = d.Scenario; 
      //a.Translations = d.Translations; 
      //a.LastModified = d.LastModified; 
      //a.ModifiedBy = d.ModifiedBy; 
      //a.LastAccessed = d.LastAccessed; 

      resources.Add(a); 
     } 



     return Ok(resources); 
    } 

Erstens gibt es einen Fehler für die "foreach ..." wie sagte

foreach nicht auf Variablen vom Typ Model arbeiten kann. Ressource, weil keine öffentliche Definition von GetEnumerator enthält.

Dann habe ich versucht, meine sproc zu ändern, um nur 1 Ergebnis zurückzukehren und die foreach Linie entfernen, dann Fehler, sagte

Ich habe

Fehler beim Deserialisieren gespeicherte Prozedur Antwort oder wandeln sie ‚Modelle zu geben. Ressource '

Ich möchte nur das Ergebnis der gespeicherten Prozedur als meine definierte Klasse (Models.Resource) zurückgeben. Wie macht man das?

+0

Nicht, dass es "der" Fehler ist, aber in Ihrer 'foreach' versuchen Sie,' a' zu 'docs' statt' d' zuzuweisen. –

+0

Sorry, das ist ein Tippfehler wenn ich kopiere ... Es sollte a = d sein; –

Antwort

0

Recht Alle, lassen Sie uns sicherstellen, dass wir auf der gleichen Seite sind.

Ich verwende den Sproc wie oben. Ich bin mit Client-Code wie folgt aus:

class Models 
    { 
     // This would have more properties, I am just using id which all docs would have. 
     public class Resource 
     { 
      [JsonProperty("id")] 
      public string Id { get; set; } 
     } 
    } 

    public async Task<IHttpActionResult> GetResources() 
    { 
     const string endpoint = "https://myservice.azure.com:443/"; 
     const string authKey = "my secret key=="; 

     var client = new DocumentClient(new Uri(endpoint), authKey); 
     Uri sprocUri = UriFactory.CreateStoredProcedureUri("db", "c1", "GetAllResources"); 

     var serializedDocs = await client.ExecuteStoredProcedureAsync<string>(sprocUri); 
     Models.Resource[] resources = JsonConvert.DeserializeObject<Models.Resource[]>(serializedDocs); 

     return Ok(resources); 
    } 

Es funktioniert gut. Machst du das?

+0

Danke Michael! Ich habe gerade gemerkt, dass mein "foreach" -Zeilenfehler aus dem Grund kommt, dass ich "[]" um die Model.Resources verpasste. Indem du das kopierst, was du vorgeschlagen hast, habe ich jetzt meine Demo laufen. Danke ~ –

1

Es kann einfacher sein sproc von Namen zu erhalten CreateStoredProcedureUri verwenden, wie folgt aus:

 const string endpoint = "https://your.service.azure.com:443/"; 
     const string authKey = "<your magic secret master key>=="; 

     var client = new DocumentClient(new Uri(endpoint), authKey); 
     Uri sprocUri = UriFactory.CreateStoredProcedureUri("databaseName", "collectionName", "GetAllResources"); 

     var result = await client.ExecuteStoredProcedureAsync<string>(sprocUri); 

Die gespeicherte Prozedur über serialisiert Ergebnisse der Abfrage (docs Array) auf String, wenn Sie es auf diese Weise zu halten, die Das Ergebnis von "sproc" wäre "string". Ich denke, Sie müssten die Objekte manuell deserialisieren. Sie können dies einfacher tun, einfach Docs von sproc zurückgeben und Ergebnisse als Objekte haben (wie Models.Resource []), die Serialisierung würde automatisch erfolgen.

Wenn Sie die gespeicherten Prozeduren ändern, nur ein Dokument zurückzukehren (zB tun __.response.setBody(docs[0]) und Models.Resource repräsentiert ein Element, dann ist der Anruf richtig:

Models.Resource doc = await client.ExecuteStoredProcedureAsync<Models.Resource>(sprocUri); 

auch, Query Dokumente // und 1. nehmen Item, würde ich nicht empfehlen, Skript zu verwenden, da das Script Overhead hat, JavsScript-Engine auszuführen. Skripte treten ein, wenn Sie Bulk-Operationen durchführen (um den Netzwerkverkehr zu optimieren) oder eine Geschäftslogik haben, die auf dem Server ausgeführt werden kann. Um das erste Element zu verwenden, können Sie eine Abfrage vom Client wie folgt durchführen: SELECT TOP 1 * FROM c. Normalerweise würden Sie die WHERE- und ORDER BY-Klausel verwenden.

Es gibt eine Reihe von docdb-Beispielen auf github, z. B. https://github.com/Azure/azure-documentdb-dotnet/tree/master/samples/code-samples/ServerSideScripts und https://github.com/Azure/azure-documentdb-dotnet/tree/master/samples/code-samples/Queries.

Danke,
Michael

+0

Danke Michael! Ich tat genau, was Sie vorgeschlagen und immer noch die "Docs" auf der foreach Zeile mit dem "GetEnumerator" -Fehler, und die gespeicherte Prozedur Ergebnis kann noch nicht deserialisiert werden, auch ich docs als Objekte
BTW, der Grund, dass ich diese Sproc erstellen ist weil ich die Leistung beschleunigen möchte. Ich habe Linq, Linq Lamda und SQL verwendet, um einige kleine Dokumente abzufragen, sie über die Web-API von Postman anzurufen. Die Sache ist alle von ihnen nehmen rund 500ms für Single-Select-Abfrage. Wir brauchen schneller als das. Deshalb versuche ich sproc. Haben Sie Vorschläge zur Beschleunigung der Abfrage? Vielen Dank! –