Showing posts with label SQL Server. Show all posts
Showing posts with label SQL Server. Show all posts

Thursday, June 16, 2016

Data Caching in a WPF


In this article I will explain how you can cache object in memory in WPF application to get better performance.

Cached data will be stored in memory so you will get faster access to that data compare to accessing it from File or Database. So whenever you need to make frequent calls to some database or file, better you cache that data and read from cached object this will improve your application performance via reducing multiple calls to database or file.

Caching mechanism provided by .Net framework 4.0. Caching is available under System.Runtime.Caching namespace and you need to add this namespace in your project references.  

See below example, where multiple calls are being made to database for getting employee details based on employee name.

XAML - 
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition />
    </Grid.RowDefinitions>
    <TextBlock Text="Name of employee - " HorizontalAlignment="Center"
               VerticalAlignment="Center"
                Grid.Row="0" Grid.Column="0" />
    <TextBox Name="EmpName" VerticalContentAlignment="Center"
             Text="{Binding Path=EmployeeName, Mode=TwoWay}"
                Height="30" Width="150" HorizontalAlignment="Center"
                VerticalAlignment="Center" Grid.Row="0" Grid.Column="1" />
    <Button Name="Search" Content="Search" Click="Search_Click"
            Grid.Row="0" Grid.Column="2" Height="30" Width="150" />
    <ListBox Height="200" Width="200" Name="EmployeeList"
                ItemsSource="{Binding}" Grid.Row="1" Grid.Column="0"
                Grid.ColumnSpan="3" />
</Grid>

Code –
public partial class MainWindow : Window
{
    ObservableCollection<string> Employees = new ObservableCollection<string>();
    public MainWindow()
    {
        InitializeComponent();
    }
    //Search Button event handler
    private void Search_Click(object sender, RoutedEventArgs e)
    {
        Employees = GetEmployeesByName(EmpName.Text);
        this.DataContext = Employees;
    }
    //Make calls to database to get employee details based on given name
    private ObservableCollection<string> GetEmployeesByName(string name)
    {
        ObservableCollection<string> employeeNames = new ObservableCollection<string>();
        string connectionString = "Data Source=MITESH-PC\\SQLEXPRESS;Initial Catalog=TestSQLDB;Integrated Security=SSPI";
        using (SqlConnection sqlConnection = new SqlConnection(connectionString))
        {
            string cmd = "select firstname + ' ' + lastname as [EmployeeName] from HR.Employees where firstname like @FirstName";
            SqlCommand command = new SqlCommand(cmd, sqlConnection);
            command.Parameters.Add(new SqlParameter("@FirstName", name));
            sqlConnection.Open();
            using (SqlDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    employeeNames.Add(reader["EmployeeName"].ToString());
                }
            }
            sqlConnection.Close();
        }
        return employeeNames;
    }
}


Output – 



In above example, for each employee search is costing database call. To avoid database call for each employee, we can cache all employee name at once and for each subsequent search we can get it from cached object. This will reduce database call every time we search on employee and increase performance. See below code which implements caching.

Code –
public partial class MainWindow : Window
{
    ObservableCollection<string> Employees = new ObservableCollection<string>();
    //cache object
    ObjectCache cache = MemoryCache.Default;
    public MainWindow()
    {
        InitializeComponent();
        //Gets all employess from database
        Employees = GetAllEmployees();
        //sets employees in cache
        cache.Set("AllEmployees",Employees, new CacheItemPolicy() { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(5) });
    }
    //Search Button event handler
    private void Search_Click(object sender, RoutedEventArgs e)
    {
        //Get employeelist from cached object
        ObservableCollection<string> employeeList =  cache["AllEmployees"] as ObservableCollection<string>;
        //if cache is expired or no object available in cache then set cache object again
        if (employeeList == null)
        {
            employeeList = GetAllEmployees();
            cache.Set("AllEmployees", Employees, new CacheItemPolicy() { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(5) });
        }
        //search employee name from employee list loaded from cache object
        var selecteEmployees = (from emp in Employees
                                where emp.ToLower().Contains(EmpName.Text.ToLower())
                                select emp).ToList();
        this.DataContext = selecteEmployees;
    }
    //Gets all employess from database
    private ObservableCollection<string> GetAllEmployees()
    {
        ObservableCollection<string> employeeNames = new ObservableCollection<string>();
        string connectionString = "Data Source=MITESH-PC\\SQLEXPRESS;Initial Catalog=TestSQLDB;Integrated Security=SSPI";
        using (SqlConnection sqlConnection = new SqlConnection(connectionString))
        {
            string cmd = "select firstname + ' ' + lastname as [EmployeeName] from HR.Employees";
            SqlCommand command = new SqlCommand(cmd, sqlConnection);
            sqlConnection.Open();
            using (SqlDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    employeeNames.Add(reader["EmployeeName"].ToString());
                }
            }
            sqlConnection.Close();
        }
        return employeeNames;
    }
}

Output – 


Output is same as above example, but in this example In-Memory caching is being used. In constructor, I loaded all the employees from database and added to the cache object. When every time user search for employee, search will be perform on in memory object and result will be returned. In this example cache expiry is set to 5 minutes but you can set as per your need. After every 5-minute cache object will get expired and employee list will be null. After cache expired, if you still need cached object then you need to load it again from database or file and add to cache again.

In memory caching is very beneficial and recommended for applications which are making multiple calls to database, file system or others. You can set cache expiry time if you want to delete or update or refresh cache object after certain time. Caching will improve performance and scalability of your application.

Hope this article helps you to understand how to cache data objects in WPF application. Please leave your feedback in comments below.


References –

See Also –


Monday, April 30, 2012

Creating simple SSIS package using SQL Server Import Export Wizard


SSIS (SQL Server Integration Services) is excellent component comes along with SQL Server. SSIS is used to perform data migration task. This is also called as ETL (Extraction, Transformation and Loading) tool. In Data warehousing applications, SSIS is used to perform various operations like importing/exporting data from different sources, perform transformation on data, doing calculation etc.

To start with SSIS, Business Intelligence Development Studio must be installed on your machine and make sure that SQL Server Integration Service is running (Start->Run-> services.msc). After that you need to create SSIS package first. Package is collection of control flow elements, data flow elements, events handlers, variables and configurations. Package is unit of work which can be debugged, executed and saved.

In this post, I will explain how to create simple SSIS package using import export wizard. SSIS has many other features which I will explain in my later posts.

Below are the steps and screenshots to create SSIS package using Import Export wizard.

1. Open Import Export Wizard from Start -> SQL Server -> Import Export Data or Open SQL Server Management Studio and write click on database from which you want to export/import data select task and Export Data.




2. SQL Server Import and Export wizard opens


3. Select source of data. (In below image I have selected SQL Server Data Source and AdventureWorks2008R2 database from where I want to export)



4. Select destination (In below image I have selected Flat File as destination there are many other options available you can select as per your requirement. You need to provide flat file name and if you want to see column name on first row check below displayed checkbox.).



5. Select Table (you can select one or more table to export data or write your own query)
  


6. Select Table from where you want to export data with row delimiter and column delimeter.


Click on Edit Mappings button to select which column data you want to export at your destination file.

Click on preview to see your data



7. Click on Save SSIS Package and File System.


8. Specify the location and name where you want to save SSIS package in local drive.

9. Verify the choices made in wizard and click on finish.



10. Package will start executing and after completion of execution check where package executed successfully or fails.



As per above image, package executed successfully and 504 rows transferred to flat file. See below image which shows column name in first row and below comma separated data.



The similar way you can import data from any source to any destination using Import and Export wizard.

Let’s have a look on created SSIS package. SSIS package has .dtsx extension. In above exercise we have created package named ProductPackage.dtsx. Double clicked on this file and it will open in Visual Studio see below screenshot.

This image shows one data flow task created on control flow tab.


On double click that task you can reach to Data Flow tab and it shows how data transfers from source to destinations.




You can also watch below video which demonstrate above mentioned all the steps and explains how create simple SSIS package using import export wizard.






Hope you liked this post. Please leave your feedback in comments section.