所有流都存储在 Dataverse 中,您可以使用适用于 .NET 的 Dataverse SDK 和 Web API 来管理它们。
本文介绍如何管理 Power Automate 的解决方案选项卡中包含的流。 目前,不支持使用代码管理我的流下的流。
与 Dataverse API 交互
Dataverse 使用适用于 .NET 的 Dataverse SDK 和 Web API 提供同等功能。
我应该使用哪个方法?
最佳方法取决于项目技术和您具有的技能。
如果您的项目使用 .NET,我们建议您使用 SDK。 SDK 通过提供类型化的对象模型和方法进行身份验证,简化您的开发体验。
详细信息:使用组织服务
如何连接?
如何连接取决于您使用的是适用于 .NET 的 Dataverse SDK 还是 Web API。
使用 SDK,您需要连接到客户端应用程序来访问 IOrganizationService 实例。 
              IOrganizationService 是一个提供可用于与 Dataverse 交互的方法的接口。
详细信息:
工作流表
云端流存储在流程(工作流)表中,该表在 Web API 中以工作流实体类型表示
下表介绍了工作流表中的重要列:
| 逻辑名称 | 类型 | 说明 | 
|---|---|---|
category | 
单选 | 流的类别。 这里是不同的类别。 0 - 经典 Dataverse 工作流。1 - 经典 Dataverse 对话。 2 - 业务规则。 3 - 经典 Dataverse 操作。 4 - 业务流程流。 5 - 现代流(自动、即时或计划流)。6 - 桌面流。 | 
clientdata | 
String | 流定义及其 connectionReferences 的字符串编码的 JSON。 | 
createdby | 
查找 | 创建流的用户。 | 
createdon | 
日期/时间 | 创建流的日期。 | 
description | 
String | 用户提供的流说明。 | 
ismanaged | 
Bool | 指示流是否通过托管解决方案安装。 | 
modifiedby | 
查找 | 更新流的最后一个用户。 | 
modifiedon | 
日期/时间 | 上一次流更新的时间。 | 
name | 
String | 您为流指定的显示名称。 | 
ownerid | 
查找 | 负责流的用户或团队。 | 
statecode | 
单选 | 流的状态。 状态可以是:0 - 草稿(关) 1 - 已激活(开)2 - 已挂起。 | 
type | 
单选 | 指示流是正在运行的流,还是可用于创建更多流的模板。  1 - 定义, 2 - 激活 3 - 模板。 | 
workflowid | 
Guid | 跨所有导入的云端流的唯一标识符。 | 
workflowidunique | 
Guid | 此流安装的唯一标识符。 | 
备注
使用 Web API,查找值是单值导航属性,可以展开来从相关记录获取详细信息。
查找列还具有可在查询中使用的相应 GUID 查找属性。 查找属性具有此命名约定:_<logical name>_value。 对于 Web API 中的工作流实体类型,您可以引用这些查找属性:_createdby_value、_modifiedby_value 和 _ownerid_value。
列出流
要检索云端流列表,可以查询工作流表。 以下查询返回当前为“开”的第一个自动流、即时流或计划流:
此静态 OutputFirstActiveFlow 方法需要经过身份验证的客户端来实现 IOrganizationService。 它使用 IOrganizationService.RetrieveMultiple 方法。
/// <summary>
/// Outputs the first active flow
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
public static void OutputFirstActiveFlow(IOrganizationService service)
{
   var query = new QueryExpression("workflow")
   {
         ColumnSet = new ColumnSet("category",
                                    "createdby",
                                    "createdon",
                                    "description",
                                    "ismanaged",
                                    "modifiedby",
                                    "modifiedon",
                                    "name",
                                    "ownerid",
                                    "statecode",
                                    "type",
                                    "workflowid",
                                    "workflowidunique"),
         Criteria = new FilterExpression(LogicalOperator.And)
         {
            Conditions = {
            {  new ConditionExpression(
               "category",
                     ConditionOperator.Equal,
                     5) }, // Cloud Flow
            {  new ConditionExpression(
                     "statecode",
                     ConditionOperator.Equal,
                     1) } // Active
         }
         },
         TopCount = 1 // Limit to one record
   };
   EntityCollection workflows = service.RetrieveMultiple(query);
   Entity workflow = workflows.Entities.FirstOrDefault();
   Console.WriteLine($"category: {workflow.FormattedValues["category"]}");
   Console.WriteLine($"createdby: {workflow.FormattedValues["createdby"]}");
   Console.WriteLine($"createdon: {workflow.FormattedValues["createdon"]}");
   // Description may be null
   Console.WriteLine($"description: {workflow.GetAttributeValue<string>("description")}");
   Console.WriteLine($"ismanaged: {workflow.FormattedValues["ismanaged"]}");
   Console.WriteLine($"modifiedby: {workflow.FormattedValues["modifiedby"]}");
   Console.WriteLine($"modifiedon: {workflow.FormattedValues["modifiedon"]}");
   Console.WriteLine($"name: {workflow["name"]}");
   Console.WriteLine($"ownerid: {workflow.FormattedValues["ownerid"]}");
   Console.WriteLine($"statecode: {workflow.FormattedValues["statecode"]}");
   Console.WriteLine($"type: {workflow.FormattedValues["type"]}");
   Console.WriteLine($"workflowid: {workflow["workflowid"]}");
   Console.WriteLine($"workflowidunique: {workflow["workflowidunique"]}");
}
要检索更多记录,删除 TopCount 限制。
输出
category: Modern Flow
createdby: SYSTEM
createdon: 5/20/2020 9:37 PM
description:
ismanaged: Unmanaged
modifiedby: Kiana Anderson
modifiedon: 5/6/2023 3:37 AM
name: When an account is updated -> Create a new record
ownerid: Monica Thomson
statecode: Activated
type: Definition
workflowid: d9e875bf-1c9b-ea11-a811-000d3a122b89
workflowidunique: c17af45c-10a1-43ca-b816-d9cc352718cf
详细信息:
创建云端流
自动化、即时和计划流的必需属性有:category、name、type、primaryentity 和 clientdata。 为这些类型的流的 primaryentity 使用 none。
此静态方法需要经过身份验证的客户端来实现 IOrganizationService。 它使用 IOrganizationService.Create 方法。
/// <summary>
/// Creates a cloud flow
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <returns>The workflowid</returns>
public static Guid CreateCloudFlow(IOrganizationService service)
{
   var workflow = new Entity("workflow")
   {
         Attributes = {
            {"category", new OptionSetValue(5) }, // Cloud flow
            {"name", "Sample flow name"},
            {"type", new OptionSetValue(1) }, //Definition
            {"description", "This flow reads some data from Dataverse." },
            {"primaryentity", "none" },
            {"clientdata", "{\"properties\":{\"connectionReferences\":{\"shared_commondataserviceforapps\":{\"impersonation\":{},\"runtimeSource\":\"embedded\",\"connection\":{\"name\":\"shared-commondataser-114efb88-a991-40c7-b75f-2693-b1ca6a0c\",\"connectionReferenceLogicalName\":\"crdcb_sharedcommondataserviceforapps_109ea\"},\"api\":{\"name\":\"shared_commondataserviceforapps\"}}},\"definition\":{\"$schema\":\"https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#\",\"contentVersion\":\"1.0.0.0\",\"parameters\":{\"$connections\":{\"defaultValue\":{},\"type\":\"Object\"},\"$authentication\":{\"defaultValue\":{},\"type\":\"SecureObject\"}},\"triggers\":{\"manual\":{\"metadata\":{\"operationMetadataId\":\"76f87a86-89b3-48b4-92a2-1b74539894a6\"},\"type\":\"Request\",\"kind\":\"Button\",\"inputs\":{\"schema\":{\"type\":\"object\",\"properties\":{},\"required\":[]}}}},\"actions\":{\"List_rows\":{\"runAfter\":{},\"metadata\":{\"operationMetadataId\":\"9725b30f-4a8e-4695-b6fd-9a4985808809\"},\"type\":\"OpenApiConnection\",\"inputs\":{\"host\":{\"apiId\":\"/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps\",\"connectionName\":\"shared_commondataserviceforapps\",\"operationId\":\"ListRecords\"},\"parameters\":{\"entityName\":\"accounts\",\"$select\":\"name\",\"$top\":1},\"authentication\":\"@parameters('$authentication')\"}}}}},\"schemaVersion\":\"1.0.0.0\"}" }
         }
   };
   return service.Create(workflow);
}
详细信息:使用组织服务创建表行
以这种方式创建的所有流的 statecode 将设置为 0(草稿或“关”)。 流需要启用才能使用。
最重要的属性是 clientdata,它包含流使用的 connectionReferences 和流的定义。 
              connectionReferences 是流使用的每个连接的映射。
{
  "properties": {
    "connectionReferences": {
      "shared_commondataserviceforapps": {
        "runtimeSource": "embedded",
        "connection": {},
        "api": { 
         "name": "shared_commondataserviceforapps" 
         }
      }
    },
    "definition": {
      "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "$connections": { "defaultValue": {}, "type": "Object" },
        "$authentication": { "defaultValue": {}, "type": "SecureObject" }
      },
      "triggers": {
        "manual": {
          "metadata": {},
          "type": "Request",
          "kind": "Button",
          "inputs": {
            "schema": { "type": "object", "properties": {}, "required": [] }
          }
        }
      },
      "actions": {
        "List_rows": {
          "runAfter": {},
          "metadata": {},
          "type": "OpenApiConnection",
          "inputs": {
            "host": {
              "apiId": "/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps",
              "connectionName": "shared_commondataserviceforapps",
              "operationId": "ListRecords"
            },
            "parameters": {
              "entityName": "accounts",
              "$select": "name",
              "$top": 1
            },
            "authentication": "@parameters('$authentication')"
          }
        }
      }
    }
  },
  "schemaVersion": "1.0.0.0"
}
更新云端流
要更新流,应仅设置要更改的属性。
此静态方法需要经过身份验证的客户端来实现 IOrganizationService。 它使用 IOrganizationService.Update 方法来更新流说明和设置负责人。
/// <summary>
/// Updates a cloud flow
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <param name="workflowid">The ID of the flow to update.</param>
/// <param name="systemuserid">The id of the user to assign the flow to.</param>
public static void UpdateCloudFlow(IOrganizationService service, Guid workflowid, Guid systemuserid) {
   var workflow = new Entity("workflow",workflowid)
   {
         Attributes = {
            {"description", "This flow will ensure consistency across systems." },
            {"ownerid", new EntityReference("systemuser",systemuserid)},
            {"statecode", new OptionSetValue(1) } //Turn on the flow.
         }
   };
   service.Update(workflow);
}
详细信息:使用组织服务 > 基本更新更新和删除表行
删除云端流
以下示例显示了如何删除表示云端流的工作流记录。
静态 DeleteCloudFlow 方法删除工作流记录。
/// <summary>
/// Deletes a workflow
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <param name="workflowId">The id of the cloud flow to delete.</param>
public static void DeleteCloudFlow(IOrganizationService service, Guid workflowId) { 
service.Delete(entityName:"workflow",id: workflowId);
}
详细信息:使用 SDK 删除记录
获取与之共享云端流的所有用户
使用 RetrieveSharedPrincipalsAndAccess 消息获取与云端流共享的所有用户的列表。
使用 SDK 时,使用 RetrieveSharedPrincipalsAndAccessRequest 类,使用 Web API 时,使用 RetrieveSharedPrincipalsAndAccess 函数。
详细信息:为主体提供访问记录的权限
共享或取消共享云端流
使用 GrantAccess 消息与任何其他 Dataverse 记录一样共享云端流。 使用 SDK 时,使用 GrantAccessRequest 类,使用 Web API 时,使用 GrantAccess 操作。 详细信息:GrantAccess 示例
如果您想要更改共享记录时授予的访问权限,使用 ModifyAccess 消息。 使用 SDK 时,使用 ModifyAccessRequest 类,使用 Web API 时,使用 ModifyAccess 操作。 详细信息:ModifyAccess 示例
要取消共享记录,使用 RevokeAccess 消息。 使用 SDK 时,使用 RevokeAccessRequest 类,使用 Web API 时,使用 RevokeAccess 操作。 详细信息:撤消访问权限
导出流
当流是解决方案的一部分时,您可以通过使用 ExportSolution 消息导出包含流的解决方案来导出流。
下面的静态 ExportSolution 示例方法使用 ExportSolutionRequest 检索包含指定 UniqueName 的非托管解决方案的 ZIP 文件的 byte[]。
/// <summary>
/// Exports an unmanaged solution
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <param name="solutionUniqueName">The uniquename of the solution.</param>
/// <returns></returns>
public static byte[] ExportSolution(
   IOrganizationService service, 
   string solutionUniqueName) 
{
   ExportSolutionRequest request = new() { 
         SolutionName = solutionUniqueName,
         Managed = false
   };
   var response = (ExportSolutionResponse)service.Execute(request);
   return response.ExportSolutionFile;
}
导入流
当您有一个解决方案 ZIP 文件时,您可以使用 ImportSolution 消息导入它。
导入流时,应设置以下参数:
| 属性名称 | 说明 | 
|---|---|
OverwriteUnmanagedCustomizations | 
如果 Dataverse 中存在这些流的现有实例,则需将此标记设为 true,以将其导入。 否则它们不会被覆盖。 | 
PublishWorkflows | 
指示导入时是否激活经典 Dataverse 工作流。 此设置不适用于其他类型的流。 | 
CustomizationFile | 
包含解决方案的 base 64 编码的 zip 文件。 | 
静态 ImportSolution 示例方法显示如何使用 ImportSolutionRequest 类导入解决方案文件
/// <summary>
/// Imports a solution.
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <param name="solutionFile">The byte[] data representing a solution file. </param>
public static void ImportSolution(
   IOrganizationService service, 
   byte[] solutionFile) {
   ImportSolutionRequest request = new() { 
         OverwriteUnmanagedCustomizations = true,
         CustomizationFile = solutionFile
   };
   service.Execute(request);
}
常见问题
api.flow.microsoft.com 的 API 怎么样?
不支持 api.flow.microsoft.com 的 API。 客户应该使用本文前面提到的 Power Automate 的 Dataverse Web API。
或者,客户可以使用管理连接器:Power Automate 管理或用于管理员的 Power Automate。
客户可以使用不受支持的 API,但 api.flow.microsoft.com 需要自行承担风险。 这些 API 可能会发生变更,因此可能会发生突破性的变更。
相关信息
              使用组织服务的实体类操作
              使用 Web API 执行操作
              共享和分配
              使用代码验证访问权限
              使用 Dataverse SDK 处理解决方案