DbToDataSet Windows Workflow Activity

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

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

        // Temporary variable for Input Arguments
        private InputArguments inputObject  = null;
        private string connectStr           = null;
        private string cmdSQL               = null;

        //Output Object
        private OutputResult OutRes = null;

        // Temporary use variable
        private DataSet dataSet             = null;
        private SqlConnection connect       = null;
        private SqlCommand command          = null;
        private SqlDataAdapter adapter      = null;
        private SqlDataReader reader        = null;

       protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
        {          
            try
            {
                // Input Object
                inputObject = inputArguments.Get(context);
                // Connection string
                connectStr  = inputObject.ConnectStrig;
                // Command string
                cmdSQL      = inputObject.SqlCommand;

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

                // If command string is empty
                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)
       {           
           try
           {
               SqlDataAdapter adapter = (SqlDataAdapter)context.UserState;
               OutRes = new OutputResult();
               // End Execute Reader
               reader = adapter.SelectCommand.EndExecuteReader(result);
               reader.Close();
               dataSet = new DataSet();
               adapter.Fill(dataSet);
               OutRes.dataSet = this.dataSet;
           }
           catch (Exception ex)
           {
               Console.WriteLine(ex.Message);
               this.OutRes.Error = ex.ToString();
           }
           finally
           {
               this.connect.Close();
           }
           return OutRes;
       }
    }
}
4. Клиент для Activity DbToDataSet.
Ниже приведен пример клиента, который организует запрос к серверу, принимает и отображает данные в DataGridView.
/* 20.09.2012
    Клиент для проверки Activity DbToDataSet.
    1. Формирует и передает на сервер объест InputArguments.
    2. Принимает и отображает объест OutputResult содержащий DataSet.
    3. Отображение приянятых данных в DataGridView.
*/
using System;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Windows.Forms;
using ClassLibrary;
using System.Diagnostics;

namespace WindowsFormsClient
{
    public partial class Form1 : Form
    {
        private ServiceReference.ServiceClient client;
        private ClassLibrary.InputArguments input;
        private ClassLibrary.OutputResult output;

        public Form1()
        {
            InitializeComponent();
            client  = new ServiceReference.ServiceClient();
            input   = new InputArguments();
            output  = new OutputResult();
            textBox2.Text = @"Data Source=PROGR\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True; Asynchronous Processing=true";
            textBox3.Text = @"SELECT Orders.OrderID, Orders.CustomerID, Orders.ShipAddress FROM Orders";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                // Clear DataSource
                this.dataGridView1.DataSource = null;
                // String for connect
                input.ConnectStrig = textBox2.Text;
                // SQL command
                input.SqlCommand = textBox3.Text;

                //  Send and receive data
                output = client.GetData(input);
                // View data
                this.dataGridView1.DataSource = output.dataSet.Tables[0];
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }
}

Visual Studio 2010 полный проект приложения можно загрузить.
C уважением, Евгений Вересов.
20.09.2012 года.