我想在 DocumentDB 中创建一个存储过程,并在以后需要时使用它。要执行存储过程,我需要知道一个 storedProcedureLink。当我使用 CreateStoredProcedureAsync 方法注册存储过程时,我得到了链接,如果我想稍后执行这个存储过程,我应该把这个链接存储在自己的某个地方吗?如果我只知道一个过程名称,我可以执行存储过程吗?从我发现的所有示例中,我似乎需要在需要执行存储过程之前创建和注册存储过程,是这样吗?
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
从我发现的所有示例中,我似乎需要在需要执行存储过程之前创建和注册存储过程,是这样吗?
不需要。存储过程的创建和注册不必在执行期间发生。
这些样本具有教育意义,但不提供真实世界的模式。请参阅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;
}
刚刚尝试了这种方法,它不起作用。
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"
}
微软现在似乎提供了一些关于如何执行存储过程的示例: https ://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.documents.client.documentclient.executestoredprocedureasync?view=azure -dotnet
您可以先在 .NET SDK 中查找数据库中的 SP
StoredProcedure storedProcedure = Client.CreateStoredProcedureQuery(GetCollection(eColl).SelfLink).Where(c => c.Id == "SP name").AsEnumerable().FirstOrDefault();