Azure 如何在DocumentDB中执行现有的存储过程?

Azure 如何在DocumentDB中执行现有的存储过程?,azure,stored-procedures,azure-cosmosdb,Azure,Stored Procedures,Azure Cosmosdb,我想在DocumentDB中创建一个存储过程,并在以后需要时使用它。要执行存储过程,我需要知道storedProcedureLink。当我用CreateStoredProcedureAsync方法注册存储过程时,我得到了链接,如果我想稍后执行此存储过程,我是否应该自己将此链接存储在某个地方?如果我只知道一个过程名,我可以执行一个存储过程吗?从我发现的所有示例来看,似乎我需要在执行存储过程之前创建并注册它,是吗?您完全可以事先创建存储过程,并将其保存在服务器上以备将来使用。您不需要在使用它之前创建

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

您完全可以事先创建存储过程,并将其保存在服务器上以备将来使用。您不需要在使用它之前创建它。这仅用于示例目的。我们希望存储过程大部分时间都已经存在,您只需在应用程序中使用它们

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

按名称查询存储过程类似于

StoredProcedure sproc = client.CreateStoredProcedureQuery(collection.StoredProceduresLink, "select * from root r where r.id = \"sproc name\"");
生成的存储过程变量将包含要执行的存储过程的SelfLink

var result = client.ExecuteStoredProcedureAsync(sproc.SelfLink);
有关如何使用存储过程的全面示例,请参阅发布于的示例中的DocumentDB.samples.ServerSideScripts项目;

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

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"
}
从我发现的所有示例来看,似乎我需要在执行存储过程之前创建并注册它,是这样吗

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

这些样本具有教育意义,但不提供真实世界的模式。看。样本也假定为单个集合。看

虽然我对DocumentDB对SQL编码约定的适应性表示赞赏,但目前的使用模式对.NET开发人员来说还不够。在SQL Server中创建CRUD存储过程,然后通过ADO.NET或数据集中的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;
    }
公共异步任务GetPunkRockerAsync(字符串分区键)
{
foreach(此.PartitionResolver.ResolveForRead(partitionKey)中的字符串collectionLink)
{
DocumentCollection collection=this.DocumentClient.CreateDocumentCollectionQuery(新Uri(this.Database.SelfLink))。其中(c=>c.SelfLink==collectionLink)。AsEnumerable().FirstOrDefault();
if(集合==null)
{
//日志。。。
继续;
}
StoredProcedure StoredProcedure=this.DocumentClient.CreateStoredProcedureRequesty(新Uri(collection.StoredProceduresLink))。其中(p=>p.Id==“GetPunkRocker”).AsEnumerable().FirstOrDefault();
if(storedProcedure==null)
{
//日志。。。
继续;
}
PunkRocker PunkRocker=wait this.DocumentClient.ExecuteStoredProcedureAsync(新Uri(storedProcedure.SelfLink),partitionKey);
if(punkRocker!=null)
{
返回朋克;
}
}
返回null;
}

您可以先在.NET SDK的DB中查找SP

StoredProcedure storedProcedure = Client.CreateStoredProcedureQuery(GetCollection(eColl).SelfLink).Where(c => c.Id == "SP name").AsEnumerable().FirstOrDefault();

Microsoft现在似乎提供了一些有关如何执行存储过程的示例:

我相信
client.CreateStoredProcedureQuery(link,String.Format(“select*from root r,其中r.id='{0}',“spname1”)).ToList().FirstOrDefault()查询id为“{0}”而不是id为“spname1”的存储过程;您应该改为在
r.id='spname'
上查询。这没有任何意义,因为string.format将在发送到DocumentDB之前创建适当的字符串。啊,是的,您是正确的!有趣的是,我只是复制粘贴并运行
client.CreateStoredProcedureQuery(link,String.Format(“select*from root r,其中r.id='{0}',“spname1”)).ToList().FirstOrDefault()并返回我的存储过程。你能发布更多更大的代码片段来提供更多的上下文吗?为什么这么难找到。。。我找到的每个示例都是关于创建存储过程的,这是第一个描述最常见的场景==执行存储过程并获取数据…如果我尝试
StoredProcedure存储过程=客户端.createstoredprocedurequiry(collection.StoredProceduresLink,“从根r中选择*,其中r.id=\“存储过程名称”)
在Visual Studio 2015中,编译器抱怨无法将类型“System.Linq.IQueryable”隐式转换为“Microsoft.Azure.Documents.StoredProcedure”Ryan CrawCour,感谢您的回答。samples链接现在是404的,所以存储过程对每个分区执行一次?如果存储过程中的查询执行类似于从根目录选择*并返回前三个的操作,该怎么办?Re:“按名称查找存储过程”:这不是有点干净吗?有缺点吗<代码>\u client.ReadStoredProcedureAsync(UriFactory.createstoredprocedururi(databaseId、collectionId、sprocId)