DbTableToXml Windows Workflow Activity

Статья описывает Windows Workflow Activity DbTableToXml. Activity разработан на языке C#. Activity выполняет чтение содержимого полей одной или нескольких таблиц базы данных, формирование на основе считанных данных DataSet, затем на основе DataSet формируется XML документ, который передается клиенту посредством Web Service WCF.
Представлен рабочий проект MS Visual Studio 2010 WCF + WorkFlow, в котором применяется описываемое Activity. В состав проекта входит WorkFlow, библиотека Activity,библиотека входных и выходных классов, Windows Form клиент запрашивающий, получающий и отображающий данные с сервера.
1. Входные данные Activity DbTableToXml.
Входные аргументы для Activity находяться в классе InputArguments и состоят из двух свойств: ConnectString - строка подключения к базе данных Northwind и SqlCommand - это SQL запрос к таблицам базы данных.
public class InputArguments
{
    public string ConnectStrig  { get; set; }
    public string SqlCommand    { get; set; }
}
2. Выходные данные Activity DbTableToXml.
Выходные аргументы для Activity находяться в класса OutputResult и состоят из двух свойств: ResultXmlDoc - выходной документ и Error - сообщения о потенциально возможной ошибке.
public class OutputResult
{
    public string ResultXmlDoc  { get; set; }
    public string Error         { get; set; }
}
3. Исходный текст Activity DbTableToXml.
Класс реализующий Activity DbTableToXml создан асинхронным, содержащим два метода:
  • BeginExecute;
  • EndExecute.
Как видно из приведенного ниже текста, SQL запрос запускается в методе BeginExecute, затем работа Activity приостаналивается и завершается процесс в методе EndExecute.
/* 14.09.2012
  1. Activity читает таблицу в базе данных Nortwind и переводит данные в DataSet, затем на основе DataSet создает XML документ.
  2. Входным параметром является класс InputArguments с полями:  
        public string ConnectStrig  { get; set; }
        public string SqlCommand    { get; set; }
  3. Выходным аргументом является класс OutputResult с полями:
        public string ResultXmlDoc  { get; set; }
        public string Error         { get; set; }
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.Xml;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Windows.Markup;
using System.ComponentModel;
using System.Xml.Linq;
using ClassLibrary;

namespace ActivityLibrary
{
    public sealed class DbTableToXml : AsyncCodeActivity<OutputResult>
    {        
        // Input Object
        [RequiredArgument]
        [DefaultValue(null)]
        public InArgument<InputArguments> inputArguments { get; set; }

        // Temporary variables
        private InputArguments inputObject      = null;
        private string connectStr               = null;
        private string cmdSQL                   = null;
        
        private DataSet dataSet                 = null;
        private SqlConnection connect           = null;
        private SqlCommand command              = null;
        private SqlDataAdapter adapter          = null;
        private StringBuilder strBuilder        = null;
        private StringWriter strWriter          = null;
        private SqlDataReader reader            = null;
        private OutputResult  OutRes            = null;

       protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
        {          
            try
            {
                // Input Object
                inputObject = inputArguments.Get(context);

                //String for connect
                 connectStr = inputObject.ConnectStrig;

                 // SQL command line
                 cmdSQL = inputObject.SqlCommand;

                 // if the connection string is empty
                if (String.IsNullOrEmpty(connectStr)) throw new ArgumentNullException("Value", "Connection String is Empty");

                // if the string is empty SQL commands
                if (String.IsNullOrEmpty(cmdSQL)) throw new ArgumentNullException("Value", "Command String is Empty");

                connect = new SqlConnection(connectStr);
                connect.Open();
                command = new SqlCommand(cmdSQL, connect);
                adapter = new SqlDataAdapter(command);
                context.UserState = adapter;
                return adapter.SelectCommand.BeginExecuteReader(callback, state);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }
        }

       protected override  OutputResult EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
       {
           SqlDataAdapter adapter = (SqlDataAdapter)context.UserState;
           OutRes = new OutputResult();
           try
           {
               //End Execute Reader
               reader = adapter.SelectCommand.EndExecuteReader(result);
               reader.Close();
               dataSet = new DataSet("All_Columns_Orders");
               adapter.Fill(dataSet);

               // Create XML file
               strBuilder = new StringBuilder();
               using (strWriter = new StringWriter(strBuilder)) { dataSet.WriteXml(strWriter); }
               OutRes.ResultXmlDoc = strBuilder.ToString();
           }
           catch (Exception ex)
           {
               Console.WriteLine(ex.Message);
               this.OutRes.Error = ex.ToString();
           }
           finally
           {
               this.connect.Close();
           }
           return OutRes;
       }
    }
}
4. Клиент для Activity DbTableToXml.
Ниже приведен пример клиента, который организует запрос к серверу, принимает и отображает данные в простом текстовом поле.
/* 14.09.2012
   Клиент для проверки Activity DbTableToXML.
   1. Формирует и передает на сервер объест InputArguments.
   2. Принимает и отображает объест OutputResult.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ClassLibrary;

namespace WindowsFormsClient
{
    public partial class Form1 : Form
    {
        ServiceReference.ServiceClient client;
        ClassLibrary.InputArguments input;
        ClassLibrary.OutputResult output;
        public Form1()
        {
            InitializeComponent();
            client = new ServiceReference.ServiceClient();
            input = new InputArguments();
            output = new OutputResult();
            // String to connect to the database
            textBox2.Text = @"Data Source=PROGR\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True; Asynchronous Processing=true";
            //SQL query
            textBox3.Text = @"SELECT Orders.* FROM Orders";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                textBox1.Text = String.Empty;
                input.ConnectStrig = textBox2.Text;
                input.SqlCommand = textBox3.Text;
                output = client.GetData(input);
                // View Result
                textBox1.Text = output.ResultXmlDoc;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }
}

Visual Studio 2010 проект содержащий: Activity, Workflow для Activity, Windows Form клиент можно загрузить.
Мы ответим на Ваши вопросы. C уважением, Евгений Вересов.
14.09.2012 года.