28 авг. 2012 г.

Как получить экземпляр рабочего процесса

Перегружая методы класса SPWorkflowEventReceiver, мы можем обрабатывать события, связанные с рабочими процессами, например, запуск и остановку РП. Единственный источник данных о РП, для которого произошло событие, это объект типа SPWorkflowEventProperties.
Кроме InstanceId и WebUrl никаких других данных, идентифицирующих РП, не предоставляется. Нормальные люди для получения экземпляра РП используют конструктор SPWorkflow(SPWeb, Guid).

Не заметив сначала этот конструктор, я решил лезть в БД содержимого для извлечения необходимой информации. Всё же забывать о БД не стоит, потому как она может пригодиться для получения, например, всех РП, запущенных на элементах узла: выбираем записи по ИД узла, группируем по ИД списка и элемента. Можно ещё и по статусу отфильтровать. Будет работать быстрее, чем обход всех списков и элементов.

using (var connection = new SqlConnection(web.Site.ContentDatabase.DatabaseConnectionString))
{
    string commandText = 
        "select ListId, ItemId, Id from Workflow where WebId='" + web.ID + "'";

    using (var command = new SqlCommand(commandText, connection))
    {
        connection.Open();

        using (var reader = command.ExecuteReader())
        {
            if (reader.Read())
            {
                Guid listId = (Guid)reader["ListId"];
                int itemId = (int)reader["ItemId"];
                Guid workflowId = (Guid)reader["Id"];

                // группируем, как надо, и возвращаем результат
            }
        }
    }
}

5 комментариев:

  1. Чет я сильно сомневаюсь что надо в БД лезть. посмотрите здесь
    http://msdn.microsoft.com/en-us/library/ms457265
    достаточно передать SPWeb и GUID workflowInstanceId
    (Initializes a new instance of a single workflow instance running on an SPWeb to be retrieved from the database.)

    ОтветитьУдалить
    Ответы
    1. Вот те на, слона-то я и не приметил. Я решил, что этот конструктор работает по типу SPWeb.Workflows или SPWorkflowCollection(SPWeb), которые возвращают только процессы, привязанные к узлу (site-based). Проверить не удосужился.

      Удалить
  2. как это делают индусы на странице /_layouts/WrkStat.aspx?List={C9E48B30-6341-4068-BC63-146F6D7FF1A2}&WorkflowInstanceID={03C35125-F3F2-4843-B82E-8BD6AC15E049}

    code in OnLoad:
    if (string.IsNullOrEmpty(this.StrGuidWorkflow))
    {
    this.StrGuidWorkflow = this.Request.QueryString["WorkflowInstanceID"];
    this.WorkflowInstanceID.Value = this.Request.QueryString["WorkflowInstanceID"];
    }
    Guid workflowInstanceId;
    try
    {
    workflowInstanceId = new Guid(this.StrGuidWorkflow);
    this.workflow = new SPWorkflow(this.Web, workflowInstanceId);
    this.wa = this.workflow.ParentAssociation;
    this.ModificationUrl = this.wa.ModificationUrl;
    this.List = SPContext.Current.List;
    }

    собственно просто вызов конструктора this.workflow = new SPWorkflow(this.Web, workflowInstanceId);

    ОтветитьУдалить