Archive

Archive for February, 2009

Configuring BizTalk 2006 R2 with Enterprise Library

February 5, 2009 Leave a comment

BizTalk is a powerful tool with a lot of out of the box features. However, there are varieties of tasks you would prefer to de-couple from BizTalk and delegate to an external framework specifically built for it. When I design software, I always pay attention to the post-deployment configurability of an application.  I always choose an approach that lets me easily change connection information, logging, exception handling, inject some logic, etc. The Microsoft Enterprise library resolves such issues perfectly. So, how would one configure BizTalk to recognize and use Enterprise library?  The answer is trivial and this blog’s purpose is just to document steps I performed to make it happen.

The first step was to install Microsoft Enterprise Library in the GAC. You can find detailed instructions in the help. I would also suggest reading Tom Hollander’s blog about managing Enterprise Library in your organization.

The second step is optional and is related to my habit to have a wrapper around 3rd party framework or solution. I have two libraries Common.Application.Exception with multiple ApplicationException descendents

and Common.EntLib.Logging in order to encapsulate some logic.

Here is an example of ErrorLogEntry with Category and Severity setting.

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Microsoft.Practices.EnterpriseLibrary.Logging;
namespace Common.Logging
{
///<summary>
/// A log entry of category Error. Default priority is High.
///</summary>
public class ErrorLogEntry : LogEntry
{
public static LogPriority DefaultPriority = LogPriority.High;
///<summary>
/// Default constructor. Default priority is High.
///</summary>
///<param name=”message”></param>
public ErrorLogEntry(string message) : this(message, DefaultPriority) { }
///<summary>
/// Constructor with basic log entry information.
///</summary>
///<param name=”message”>Message to be logged.</param>
///<param name=”priority”>Priority of the log entry (low, high, etc.).</param>
public ErrorLogEntry(string message, LogPriority priority)
: base()
{
this.Categories.Add(LogCategories.Error);
Priority = (int)priority;
Severity = TraceEventType.Error;
Message = message;
}
}
}

Obviously, these Libraries has to be signed and deployed to the GAC 

The next step is to configure BizTalk run-time.  Before you do it, DO MAKE A COPY of BTSNTSvc.exe.config. Then open Enterprise Library Configuration console pointing to the BTSNTSvc.exe.config under C:\Program Files\Microsoft BizTalk Server 2006 folder and configure application blocks you intend to use within yours BizTalk applications.

To test an enterprise library call, I have created a simple orchestration with a receive shape and trigger message.

I also added Expression shape to call Enterprise Library.

Dropping trigger message into configured location produces expected Event log message.

I modified configuration by adding new Flat file trace listener

Then I added new trace listener to the Debug category .

The result appeared in two different destinations without modifying any BizTalk artifacts.

Enjoy

Technorati Tags: ,

Categories: BizTalk

Using Stored Procedure with ADO.NET Entity framework

February 4, 2009 Leave a comment

I think that Microsoft ADO.NET Entity framework (EF) has a big future which goes beyond just an ORM area. However, the first release is not perfect. Erik Kindblad discusses bunch of shortfalls of VS 2008 SP1 EF implementation. The biggest one is inability to map Entity to the stored procedure. My believe is that in the production environment the access to the tables has to be revoked and the only way to access the data in the table would be a stored procedure. I found several good articles aiming to resolve the same issue, but most of them require additional coding. Then I looked at edmx file to see what mapping xml has been produces by EF designer.

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
<!– EF Runtime content –>
<edmx:Runtime>
<!– SSDL content –>
<edmx:StorageModels>
<Schema Namespace="ClinetSODAModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2005" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">
<EntitySet Name="Barrier" EntityType="ClinetSODAModel.Store.Barrier" store:Type="Tables" store:Schema="dbo" store:Name="Barrier">
<DefiningQuery>
SELECT
[Barrier].[Barrier_CD] AS [Barrier_CD]
,[Barrier].[Description] AS [Description]
,[Barrier].[Last_Mod_Dt] AS [Last_Mod_Dt]
,[Barrier].[Last_Mod_ID] AS [Last_Mod_ID]
FROM [dbo].[Barrier] AS [Barrier]
</DefiningQuery>
</EntitySet
 

My first reaction was to put stored procedure call instead of the SELECT statement.

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
<!– EF Runtime content –>
<edmx:Runtime>
<!– SSDL content –>
<edmx:StorageModels>
<Schema Namespace="ClinetSODAModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2005" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">
<EntitySet Name="Barrier" EntityType="ClinetSODAModel.Store.Barrier" store:Type="Tables" store:Schema="dbo" store:Name="Barrier">
<DefiningQuery>
EXEC [dbo].[sp_GetAllBarrier]
</DefiningQuery>
</EntitySet>

The T-SQL generated by EF run-time failed, but gave me a material to play with

SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT cast(1 as bit) AS X ) AS [SingleRowTable1]
LEFT OUTER JOIN (SELECT
    COUNT(cast(1 as bit)) AS [A1]
    FROM (
EXEC [dbo].[sp_GetAllBarrier]
) AS [Extent1] ) AS [GroupBy1] ON 1 = 1

 

Finally, I found a construct that would let me to use stored procedure.

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
<!– EF Runtime content –>
<edmx:Runtime>
<!– SSDL content –>
<edmx:StorageModels>
<Schema Namespace="ClinetSODAModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2005" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">
<EntityContainer Name="ClinetSODAModelStoreContainer">
<EntitySet Name="Barrier" EntityType="ClinetSODAModel.Store.Barrier" store:Type="Tables" store:Schema="dbo" store:Name="Barrier">
<DefiningQuery>
SELECT * FROM OPENQUERY(LOCALSERVER, ‘EXEC SODA.dbo.sp_GetAllBarrier’)
</DefiningQuery>
</EntitySet>
 

Yes, it would require me to register local server

sp_addlinkedserver @server = ‘LOCALSERVER’, @srvproduct = ,
@provider = ‘SQLOLEDB’, @datasrc = @@servername

 

And the usage of full stored procedure name including DB name is not convenient, but step forward and buys some time before Microsoft issues new EF release.

Categories: Entity Framework