3

我想在 DocumentDB 中创建一个存储过程,并在以后需要时使用它。要执行存储过程,我需要知道一个 storedProcedureLink。当我使用 CreateStoredProcedureAsync 方法注册存储过程时,我得到了链接,如果我想稍后执行这个存储过程,我应该把这个链接存储在自己的某个地方吗?如果我只知道一个过程名称,我可以执行存储过程吗?从我发现的所有示例中,我似乎需要在需要执行存储过程之前创建和注册存储过程,是这样吗?

4

5 回答 5

5

您绝对可以事先创建存储过程并将其保存在服务器上以供将来使用。您不需要在使用它之前创建它。这仅用于示例目的。我们预计大多数情况下存储过程已经存在,您只需在应用程序中使用它们。

您确实需要 SelfLink 来执行存储过程。一种方法是查询存储过程(按名称),获取 SelfLink,然后使用它来执行存储过程。

按名称查询存储过程看起来像:

StoredProcedure sproc = client.CreateStoredProcedureQuery(collection.StoredProceduresLink, "select * from root r where r.id = \"sproc name\"");

生成的 sproc 变量将包含您要执行的存储过程的 SelfLink。

var result = client.ExecuteStoredProcedureAsync(sproc.SelfLink);

有关如何使用存储过程的综合示例,请参阅发布的示例中的 DocumentDB.Samples.ServerSideScripts 项目; http://code.msdn.microsoft.com/Azure-DocumentDB-NET-Code-6b3da8af

于 2014-09-11T17:56:43.537 回答
2

从我发现的所有示例中,我似乎需要在需要执行存储过程之前创建和注册存储过程,是这样吗?

不需要。存储过程的创建和注册不必在执行期间发生。

这些样本具有教育意义,但不提供真实世界的模式。请参阅DocumentManagement 基本 CRUD 操作。样本也假设一个集合。请参阅分区基本 CRUD 操作

虽然我对 DocumentDB 对 SQL 编码约定的适应表示赞赏,但目前的使用模式对于 .NET 开发人员来说还不够。十年前在 SQL Server 中创建 CRUD 存储过程,然后通过 ADO.NET 或 DataSet 中的 TableAdapter 按名称调用它们的模式在 DocumentDB 中不起作用。

如果我只知道一个过程名称,我可以执行存储过程吗?

是的,但它并不漂亮:

StoredProcedure storedProcedure = this.DocumentClient.CreateStoredProcedureQuery(new Uri(collection.StoredProceduresLink)).Where(p => p.Id == "GetPunkRocker").AsEnumerable().FirstOrDefault();

使用 PartitionResolver 时,事情变得更加复杂:

    public async Task<PunkRocker> GetPunkRockerAsync(string partitionKey)
    {
        foreach (string collectionLink in this.PartitionResolver.ResolveForRead(partitionKey))
        {
            DocumentCollection collection = this.DocumentClient.CreateDocumentCollectionQuery(new Uri(this.Database.SelfLink)).Where(c => c.SelfLink == collectionLink).AsEnumerable().FirstOrDefault();

            if (collection == null)
            {
                // Log...
                continue;
            }

            StoredProcedure storedProcedure = this.DocumentClient.CreateStoredProcedureQuery(new Uri(collection.StoredProceduresLink)).Where(p => p.Id == "GetPunkRocker").AsEnumerable().FirstOrDefault();

            if (storedProcedure == null)
            {
                // Log...
                continue;
            }

            PunkRocker punkRocker = await this.DocumentClient.ExecuteStoredProcedureAsync<PunkRocker>(new Uri(storedProcedure.SelfLink), partitionKey);

            if (punkRocker != null)
            {
                return punkRocker;
            }
        }

        return null;
    }
于 2015-09-30T18:54:13.563 回答
0

刚刚尝试了这种方法,它不起作用。

client.CreateStoredProcedureQuery( link, String.Format( "select * from root r where r.id = '{0}'", "spname1" ) ).ToList(  ).FirstOrDefault( );

返回空

client.CreateStoredProcedureQuery( link, String.Format( "select * from root r" ) ).ToList( ).FirstOrDefault( );

返回正确的存储过程

{
    "id": "spname1",
    "body": "function() {  
        var context = getContext();
        var collection = context.getCollection();       
    }",
    "_rid": "XXX",
    "_ts": 1410449011.0,
    "_self": "XXX",
    "_etag": "XXX"
}
于 2014-09-11T19:37:26.760 回答
0

微软现在似乎提供了一些关于如何执行存储过程的示例: https ://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.documents.client.documentclient.executestoredprocedureasync?view=azure -dotnet

于 2018-07-27T12:50:50.573 回答
0

您可以先在 .NET SDK 中查找数据库中的 SP

StoredProcedure storedProcedure = Client.CreateStoredProcedureQuery(GetCollection(eColl).SelfLink).Where(c => c.Id == "SP name").AsEnumerable().FirstOrDefault();
于 2016-03-27T12:32:49.093 回答