Una primera mirada a WCF & WF en el .NET Framework 3.5

Hola muchachos!!!, estuve investigando acerca de que trae de nuevo WCF y WF en el .NET Framework 3.5. En base a eso desarrolle un simple ejemplo con el Orcas March CTP, el conocidisimo HelloWorld. En este post voy a tratar de darles una primera mirada a WCF & WF en el .NET Framework 3.5 (a.k.a Silver) con este sencillo ejemplo.

Estos son los pasos para desarrollar la aplicacion de ejemplo, HelloWorld:

  1. Crear un proyecto WCF Service Library.
    • Este es el project template para hostear el servicio WCF en la aplicacion WCF Service Host, esta hostea todos los servicios que se configuren en el App.config del servicio. 
    • Este es el service contract:
      using System;
      using System.Collections.Generic;
      using System.Text;
      using System.ServiceModel;
      
      namespace HelloWorldService
      {
          [ServiceContract()]
          public interface IHelloService
          {
              [OperationContract()]
              string GetHelloWorld();
          }
      }

    • y esta la implementacion del servicio:
      using System;
      using System.Collections.Generic;
      using System.Text;
      
      namespace HelloWorldService
      {
          public class HelloService : IHelloService
          {
              #region IHello Members
      
              public string GetHelloWorld()
              {
                  return "Hello,
                      World!";
              }
      
              #endregion
          }
      }

  2. Crear un proyecto Sequential Workflow Console Application.
    • Este proyecto es el cliente que contiene el Sequential Workflow, HelloWorldWorkflow.

  3. Crear el App.Config:
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
        <system.serviceModel>
            <client>
                <endpoint address="http://localhost:8008/hello"
                    binding="wsHttpBinding"
                    bindingConfiguration=""
                    contract="HelloWorldService.IHelloService"
                    name="EndPointHelloWorld" />
            </client>
        </system.serviceModel>
    </configuration>

  4. Agregar una SendActivity al HelloWorldWorkflow.
    • SendActivity se utiliza para enviar y para recibir un mensaje a traves de un endpoint de WCF. Su uso es bastante directo.
    • Agreguen una SendActivity al HelloWorldWorkflow y denle una mirada a las Propiedades de esta activity.  
      • Primero seteamos la propiedad ServiceOperationInfo. Para ello le damos click sobre las ellipsis (…) y se abre la ventana Choose Operation. Presionamos sobre Import para importar el service contract HelloWorldService.IHelloService.
      • Seleccionamos el metodo GetHelloWorld para terminar de setear la propiedad ServiceOperationInfo.
      • Luego de setear la propiedad ServiceOperationInfo, aparecera la propiedad Return, esta es una propiedad Binding y debemos setearla con un Dependency Property. Para ello le damos click sobre las ellipsis (…) y seleccionamos Bind to new member en la ventana que se abre. Aca creamos una nueva dependency property, a la cual llamamos Answer.
      • Por ultimo seteamos la propiedad EndPoint, utilizando los endpoints que configuramos en el App.config.
        • ConfigurationName: EndPointHelloWorld
        • OwnerActivityName: EndPointHelloWorld
    • Finalmente, para mostrar los resultados, agregamos un  Code activity al HelloWorldWorkflow. Hacemos doble click sobre la Code activity y pegamos el siguiente codigo:
      private void codeActivity1_ExecuteCode(object sender, EventArgs e)
      {
             Console.WriteLine(Answer);
             Console.Read();
      }

  5. Para terminar con este ejemplo, necesitamos resolver algunos problemas que tiene Orcas:
    • WF Project templates tiene mal seteado la version del framework; Esto genera, que al intentar utilizar assemblies mayores que 3.0.0.0, el proyecto falle.
      • Solution: click derecho sobre el proyecto, seleccionamos properties, y cambiamos la version del framework a 3.5.0.0
    • Un ServiceHost no lee las settings porque el App.config no se copia a la carpeta Bin, (solamente sobre Windows Server 2003):  Esto genera que al correr la aplicacion, nos tire la siguiente exception "no application endpoints can be found"
      • Solution: agregar el siguiente Post Build Event "copy “$(ProjectDir)\app.config” $(TargetName).config "

Bueno, esta fue una primera mirada a WCF & WF en el .NET Framework 3.5. Espero que les haya gustado :-)

Aca les dejo el codigo.

Tagged

Hi guys, I’ve been tagged by Juan Pablo Garcia.

Some here are mine:

  1. My first computer was a Commodore 128 where I’ve gaven my first steps in the programming with the language Basic.
  2. I’m descending of Japanese by part of my grandparents, for that reason I like the sushi. :)
  3. I’m 23 years old and I’m live in Argentina with my parents. I’m work for Southworks and I study system engineer at UCEMA.
  4. I like the whisky, the fernet with cola and the partys. :)
  5. I play soccer. I like the music and my favourite band is Los Fabulosos Cadillacs.

Now, I pass the ball to: Edgardo Rossetto, Miguel Saez, Alberto Ortega, Juan Arguello y Hernan Alberti.

Windows PowerShell Scripts: Errors handling

Trabajando sobre unos scripts de PowerShell para testear la funcionalidad de unos assemblies, tenia que encontrar la forma de manajear los errores en PowerShell. Encontre este post y este capitulo Error Handling and Debugging del libro de Jones & Hicks sobre PowerShell.

Segui este post y lei el capitulo Error Handling and Debugging para entender como PowerShell maneja los errores.

En base a esto, implemente el trap handler en los scripts para manejar todos los errores:

trap {
      write-host "An error occured: "
      write-host "Message: " $_.Exception.Message
      throw
}

Pero esto, solamente maneja los errores producidos por los cmdlets (Command Lets).  En mi caso tambien se queria manejar los errores que puedan surgir al invocar metodos del assembly.

Esta es la parte del script en donde si hay un error el trap no lo agarra:

$da = new-object Restaurants.DataAccess.Queries.RestaurantQueries "Data Source=.\SQLEXPRESS;Initial Catalog=DinnerNow;Integrated Security=True"

$rest = $da.GetRestaurant("7a56fe1b-c516-4e6e-8f75-339bb25a634d")

Si ejecutamos el script y el metodo al que se llama no esta implementado, por ejemplo, el script falla pero sigue ejecutandose. 

PS Handle Error - No

Figura 1: Se puede observar que ha ocurrido un error y el script termina su ejecucion sin tener en cuenta este.

Para resolver esto, preguntamos si el metodo existe y utilizamos el Command Let write-error para setearle un mensaje al error y la accion a ejecutar:

$da = new-object  Restaurants.DataAccess.Queries.RestaurantQueries "Data Source=.\SQLEXPRESS;Initial Catalog=DinnerNow;Integrated Security=True"

if ($da.GetRestaurant)
{
      $rest = $da.GetRestaurant("7a56fe1b-c516-4e6e-8f75-339bb25a634d")
}
else
{
      write-error -message "Cannot find method GetRestaurant" - ErrorAction Stop
}

De esta manera el trap agarra el error y se puede setear para que el script pare la ejecucion.

PS Handle Error - SI

Figura 2: Se puede observar que se informa que ha ocurrido un error y el script ha detenido su ejecucion.

Posted in Uncategorized. Tags: . No Comments »

SQL Server 2000 - Performance: Stored Procedure

Tips for the optimization of Stored Procedure:

  • Include the SET NOCOUNT ON statement into your stored procedures to stop the message indicating the number of rows affected by a Transact-SQL statement.
    This can reduce network traffic, because your client will not receive the message indicating the number of rows affected by a Transact-SQL statement.

 

  • Call stored procedure using its fully qualified name.
    The complete name of an object consists of four identifiers: the server name, database name, owner name, and object name. An object name that specifies all four parts is known as a fully qualified name. Using fully qualified names eliminates any confusion about which stored procedure you want to run and can boost performance because SQL Server has a better chance to reuse the stored procedures execution plans if they were executed using fully qualified names.

 

  • Consider returning the integer value as an RETURN statement instead of an integer value as part of a recordset.
    The RETURN statement exits unconditionally from a stored procedure, so the statements following RETURN are not executed. Though the RETURN statement is generally used for error checking, you can use this statement to return an integer value for any other reason. Using RETURN statement can boost performance because SQL Server will not create a recordset.

     

  • Don't use the prefix “sp_” in the stored procedure name if you need to create a stored procedure to run in a database other than the master database.
    The prefix “sp_” is used in the system stored procedures names. Microsoft does not recommend to use the prefix “sp_” in the user-created stored procedure name, because SQL Server always looks for a stored procedure beginning with “sp_” in the following order: the master database, the stored procedure based on the fully qualified name provided, the stored procedure using dbo as the owner, if one is not specified. So, when you have the stored procedure with the prefix “sp_” in the database other than master, the master database is always checked first, and if the user-created stored procedure has the same name as a system stored procedure, the user-created stored procedure will never be executed.

     

  • Use the sp_executesql stored procedure instead of the EXECUTE statement.
    The sp_executesql stored procedure supports parameters. So, using the sp_executesql stored procedure instead of the EXECUTE statement improve readability of your code when there are many parameters are used. When you use the sp_executesql stored procedure to executes a Transact-SQL statements that will be reused many times, the SQL Server query optimizer will reuse the execution plan it generates for the first execution when the change in parameter values to the statement is the only variation.

     

  • Use sp_executesql stored procedure instead of temporary stored procedures.
    Microsoft recommends to use the temporary stored procedures when connecting to earlier versions of SQL Server that do not support the reuse of execution plans. Applications connecting to SQL Server 7.0 or SQL Server 2000 should use the sp_executesql system stored procedure instead of temporary stored procedures to have a better chance to reuse the execution plans.

     

  • If you have a very large stored procedure, try to break down this stored procedure into several sub-procedures, and call them from a controlling stored procedure.
    The stored procedure will be recompiled when any structural changes were made to a table or view referenced by the stored procedure (for example, ALTER TABLE statement), or when a large number of INSERTS, UPDATES or DELETES are made to a table referenced by a stored procedure. So, if you break down a very large stored procedure into several sub-procedures, you get chance that only a single sub-procedure will be recompiled, but other sub-procedures will not.

 

  • If possible, avoid using SQL Server cursors.                                     They generally use a lot of SQL Server resources and reduce the performance and scalability of your applications. If you need to perform row-by-row operations, try to find another method to perform the task.  Here are some alternatives to using a cursor:
    • Use WHILE LOOPS
    • Use temp tables
    • Use derived tables
    • Use correlated sub-queries
    • Use the CASE statement
    • Perform multiple queries                                                                 

There are several reasons that I use temporary tables: to hold the results of a called stored procedure, to reduce the number of rows for joins, to aggregate data from different sources, or to replace cursors.

Posted in Uncategorized. Tags: . No Comments »

SQL Server 2000 issue: Stack Overflow

When generate Dynamic SQL that contains a large number of UNION ALL and queries generated is long, the execute generate Stack Overflow.

select pedido_id , cliente_id

from (select 1 as pedido_id union all select 2 as pedido_id union all select 3 as pedido_id union all select 4 as pedido_id … union all select 15751 as pedido_id)

Rewrite the query and use a #temp table to contain the values in the UNION ALL:

create table #tempTable

(

pedido_id int

)

insert into #tempTable

select 1 as pedido_id union all select 2 as pedido_id union all select 3 as pedido_id union all select 4 as pedido_id … union all select 15751 as pedido_id

Thus east mitigate this issue.

 

Other reason for that generate Stack Overflow, see:

  • Install SQL Server 2000 SP4, this SP contains:
    • FIX: Query on the sysmembers virtual table may fail with a stack overflow
    • FIX: Merge replication reconciler stack overflow

http://support.microsoft.com/kb/888799/en-us

Download!

 

If your queries that contain a large number of arguments (thousands) inside an IN or a NOT IN clause:

http://support.microsoft.com/kb/288095/en-us

Posted in Uncategorized. Tags: . No Comments »