Posts

....
Technical Blog for .NET Developers ©

Sunday, October 28, 2012

Calling WCF Async

When our applications call a web service, either from desktop apps or web sites, we have to keep in mind its response times

There is a mechanism for calling the web service asynchronously. Let's take the example exposed in this link, WCF Services, and configure the service reference to generate asynchronous operations



There are two different ways to achieve the process

With the next code, we are assigning a handler to the GetElementsCompleted event, so the application will work on other tasks while is waiting for the event triggers

     
private void btnGetElements_Click(object sender, EventArgs e)
{
    try
    {
        client = new ChemicalServiceClient();
        client.GetElementsCompleted += 
         new EventHandler<GetElementsCompletedEventArgs>(client_GetElementsCompleted);
        client.GetElementsAsync();
    }
    catch (FaultException<AccessFault> ex)
    {
        lblResult.Text = ex.Message + ex.Detail.ExceptionType + ex.Detail.StackTrace;
    }
}

void client_GetElementsCompleted(object sender, GetElementsCompletedEventArgs e)
{
    dgvElements.DataSource = e.Result.ToList();
    lblResult.Text = e.Result.Length.ToString() + " elements were found";
}


The second way is an asynchronous call itself, with the implementation of a callback function, it generates a separated thread to manage the call

The code is as follows

     
private void btnInsertElement_Click(object sender, EventArgs e)
{
    try
    {
        client = new ChemicalServiceClient();
        Element elemToInsert = new Element()
        {
            AtomicSymbol = txtAtomicSymbol.Text,
            Name = txtName.Text,
            LatinName = txtLatinName.Text
        };

        client.BeginInsertElement(elemToInsert, InsertAsyncCallBack, null);
    }
    catch (FaultException<AccessFault> ex)
    {
        lblResult.Text = ex.Message + ex.Detail.ExceptionType + ex.Detail.StackTrace;
    }
}

private void InsertAsyncCallBack(IAsyncResult asyncResult)
{
    if (asyncResult.IsCompleted)
    {
        string elemKey = client.EndInsertElement(asyncResult);
        lblResult.Text = elemKey + " was added correctly";
    }
}


This second way is the recommended for web scenarios, because the site will renders immediatly after the function call, instead of wait for the event fires


<METHOD SOFTWARE © 2012>

Monday, October 15, 2012

T-SQL Case Sensitive Queries

During the process of installation of SQL Server, we have to set up the collation options. This step will determine the result of every query we launch



In the case that we had configured a case insensitive collation, we must be aware of many cases require a case sensitive query, for example a user/key value

There are four ways for achieving case sensitive queries despite of the configured collation

1. We can rebuild our databases specifying the new collation, so we get the change at server level

Setup /QUIET /ACTION=REBUILDDATABASE /INSTANCENAME=InstanceName /SQLSYSADMINACCOUNTS=accounts /[ SAPWD= StrongPassword ] /SQLCOLLATION=CollationName

For more information, see msdn documentation --> MSDN: Set or Change the Server Collation

2. We can set up the collation only for our database, so we get the change at database level

To retrieve the actual collation of our database, we can launch the next query

     
    SELECT name, collation_name 
    FROM sys.databases
    WHERE name = 'Business'
    


To get a list of the available collations, we launch the next query, this query will also returns a description of the conditions for the collation

    SELECT * FROM ::fn_helpcollations()


The command to change the collation of our database is the next, where _CS_ indicates case sensitive

    ALTER DATABASE Business COLLATE Modern_Spanish_CS_AS   


3. In the same way as prior, we can change the collation at column level

    ALTER TABLE B_CUSTOMERS 
    ALTER COLUMN CustomerKey varchar(20)COLLATE Modern_Spanish_CS_AS NOT NULL


4. And finally, if we don't have access to release these kind of changes, we can query the column casting the varchar datatype to varbinary, so we will compare the varchar values through its binary code

     
CREATE PROCEDURE LOGIN_CUSTOMER
    (@nick VARCHAR(20), @customerkey VARCHAR(20), @res BIT OUTPUT)
AS BEGIN

    IF EXISTS 
        (SELECT 1 FROM B_CUSTOMERS
         WHERE Nick = @nick
         AND    
            CAST(CustomerKey AS VARBINARY(20)) 
             = 
            CAST(@customerkey AS VARBINARY(20)))

        SET @res = 1                
        
    ELSE    
        SET @res = 0

    RETURN @res
END
GO 


With this option, we can be sure that the query will perform correctly


<METHOD SOFTWARE © 2012>