Friday, March 5, 2010

Can I use Microsoft Entity Framework in production products?

My team building a monitoring administration front-end WPF application. of course, we have a lot of data stored in a database and we need to show the end-user a view from this data. I’ve been asked to choose our DAL and Entity technology and design the business-objects.

My first decision was to use LINQ and anonymous-type in the front end. this is mainly because the application is for monitoring only and there’s no updates or insert operations.

The next step was the data layer and the Entity technology. I don’t like writing XML by hand (who does?) and I really prefer drugging shapes from the visual studio tool box and (hopefully) auto generate code behind. so NHibernat is out of the game for me. Now, I needed to choose between LINQ to SQL and ADO.NET Entity framework which both comes with a visual studio 2008 designer.

My first attempt was EF because it suppose to replace LINQ to SQL (is it just so?)

Like everyone, I saw EF demos working when executing INSTER/UPDATE/DELETE stored procedures mapping exactly to a table entity, but in my case, I need a custom entity based on a table view and stored-procedure result.

I’ve fight with EF (on VS2008) for almost all day long and it appears that EF (currently) doesn't supports out-of-the-box entity generation from SP and Views. I did find workarounds but I don’t consider workaround as a reliable solution. 

Honestly, I find that really odd…

Every production real-world environment works with SP and view, so I just can’t understand what was the point of releasing a framework that missing basic requirements for a production use…

For the guys in Redmond, I just have to say that there are some companies that taking your produces seriously, so please, stop with those semi-CTP frameworks. If you are releasing a product, try give another thought of productivity. Sorry to say but, currently, EF is great for ORM demos and presentations but not for real-world systems.

Currently, I’ll use LINQ to SQL.

Thursday, December 17, 2009

C# 3.5 course code samples

I've spend the last past week teaching 26 talented and wonderful students.

It was a course on .Net 3.5 includes WCF, WPF, C# 3.5 features and also some important concepts that every integration-developer should follow like:

  • Think XSD and not just OO
  • Don’t leave an ugly WSDL behind you (because auto generated code will be as ugly as your WSDL)

This post is for them.

- I had a great time with you and I hope you’ll find my tips useful.

As I promised, You can download the course code samples (all of them!) from Here

Tuesday, August 25, 2009

Pnyxe - a new commenting system in my blog

As all of you readers can see, I’ve decided to adjust the commenting system of my blog into a bright, easy to use one.

I’m now using the beautiful system founded by Amit monbaz (a good friend) and so-called Pnyxe

I’m currently moving all the comments you’ve posted in Blogger to the new system, so, I’m apologize if you previously posted a comment and now you notice that its missing – I promise to show them all again within Pnyxe comments system.

Also, I hope you’ll enjoy my new comments system. please don’t hesitate to share your thoughts with me and the other readers.

Happy posting to everyone.

Tuesday, April 7, 2009

My Resume

I’m not officially seeking for a new position but if you interested, you can follow this link to find my Resume.

I haven't been posting for a while, but - coming really soon my next post about Microsoft WCF vs. Java SCA and what this mean in the BizTalk perspective.

Wednesday, December 17, 2008

Managing a BizTalk 2006 MSI deployment packages

One of the features of BizTalk 2006 deployment module is the ability to export and import a BizTalk Application as MSI installation package.

In this way we can treat each application as an atomic deployment package. This means that if we need to update our application resources with a new version, we can create a new MSI version 2.0 with all new versions of the resources and then deploy them all in one managed package.

The creation of the MSI package can be done from within the Administration Console MMC or through BTSTask.exe script.

 

or with BTSTask.exe:

ExportApp -ApplicationName:MyApp -Package:"C:\Temp\MyApp.Msi"

To see BTSTask.exe usage:

C:\Program Files\Microsoft BizTalk Server 2006>BTSTask.exe ExportApp -?

All BizTalk Exported MSI files are always versioned ‘1.0.0.0’

Both BizTalk Administration console and BTSTask.exe sharing the same API to create this MSI file. The methods and classes to administrate BizTalk reside under Microsoft.BizTalk.ApplicationDeployment.Application namespace of assembly Microsoft.BizTalk.ApplicationDeployment.Engine.

The method that actually creates the MSI package is

CreateMsiPackage(string msiPath, ICollection<Resource> resources, ICollection<string> applicationReferences, IDictionary<string, object> requestProperties)

Now, unfortunately by using this method, BizTalk always creates the MSI file version as 1.0.0.0 – this means that we can’t easily manage our MSI installation packages because even if we're creating MSI of version 2.0, BizTalk will export it as 1.0  

This restriction is for some reason hard-coded and you just can't change it.

in the following figure you can see the hard-coded msi version:

 

How can I change the MSI version and successfully manage my installation packages

One of the ways I’ve seen people handling this restriction is by simply name the generated  MSI installation Package with some Naming-Conventions like <ApplicationName>_<VerNum>.MSI

I consider a file name as a poor way to ensure version identity, a better idea is to somehow "Patch" the MSI metadata itself to hold the correct version. in this way, I can assure that no one will accidently rename my MSI file (just think on how easy that can happen).

What is BizTalk MSI installation package

Before I'll show you how to patch the file, it's first must be understood that an MSI file is actually a Database file. Inside the MSI there's some system table that contains a lot of data like parameters of the MSI, the name of the CAB files, the Binary stream data content of the CAB files, custom actions etc.

The MSI Installer engine executes SQL queries against the MSI tables and by that installing and extracting the actual files. the functions required to work with MSI protocol can be reference through msi.dll unmanaged DLL under windows system directory.

You can find the MSI database documentation on MSDN here

Browse into BizTalk MSI

The best way to know what MSI in general (and BizTalk MSI file in particular) means is by using "Microsoft Orca".

As you can see in the figure above, the version of the MSI is saved in 'ProductVersion' cell under 'Property' table.

So, the solution to BizTalk hard-coded 1.0 version problem is to change this value inside 'Property' table. but how can we get inside the MSI tables and change this value? – one way is by using a tool like Microsoft Orca, but in this way, the developer (or administrator) must patch the file by hand and it’s a path to future mistakes. I consider it to be a good solution only if we can some-how automate the process afterwards, so some like always some C# code can do the trick.

Patching BizTalk MSI file

BizTalk ships with a helper class to manage MSI and CAB files. The assembly name is Microsoft.BizTalk.MSIManager.dll

This class is actually a managed code wrapper around the MSI.dll functions and mach more easy to code then PInvoke. BizTalk infrastructures API's for deployment uses this class to create and import files form BizTalkMgmtDb into an MSI installer file and vise versa.

So, now we understand that we can't force BizTalk to export the MSI with another version then 1.0.0.0 but we can still use BizTalk helper classes to get an easy access the MSI tables and to change the information holds inside the exported MSI.

Here's the code snippet:

        public void UpdateMSIProps(string msiPath, string version)

        {

            Database db = Installer.OpenDatabase(msiPath, DatabaseOpenMode.Transact);

            string query = @"UPDATE Property SET Property.Value = '" + version + "' WHERE Property.Property = 'ProductVersion'";

            Record rec = null;

            Microsoft.BizTalk.ApplicationDeployment.MSIManager.WindowsInstaller.View vw =

            db.OpenView(query);

            vw.Execute();

            vw.Close();

           

            db.Commit();

            db.Close();

            db.Dispose();

        }

I also guess you’ll probably want to automate following steps as a script:

  • BTSTask.exe -AddResource
  • BTSTask.exe -ExportApp
  • Patch MSI
  • Move MSI to the destination MSI's folder.

Conclusion

Although BizTalk can export Application from BizTalkMgmtDb into a MSI installer package, it’s also forces this package to be of version 1.0.0.0

we simply can't do much with that because it's hard-coded with BizTalk deployment API but we does can take the newly generated MSI and 'Patch' the correct table with our desired version.

In this way we can handle our MSI versioning in the correct way.

Thanks’ to Moti Feldman for helping me with this issue.

Wednesday, September 24, 2008

BizTalk 2006 MMC snap-in limitation

No doubt BizTalk 2006 MMC snap-in is a great move forward since the days of BizTalk 2004 Explorer Add-in. although, the GUI itself suffers sometimes from a problem or another. I think the mostly common problems are missing features or incomplete implementation. one example is when you try to start application. you can right click on the BizTalk application name and choose start. in this case, BizTalk administration console consider the activity to be under one 'transaction' so if one orchestration in one application fails in the start process - all other orchestrations, send-ports etc. in the whole application will automatically rollback to the previous state.

The reason is that under the surface the GUI is using Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer class (please note that it's actually also make use of Microsoft.BizTalk.ApplicationDeployment.Group class - but I'll ignore that for the moment).  when you creates instance of this class and make some changes to send-port etc. the change will not reflect to BizTalkMgmtDb until a call to the SaveChanges() method.

If I could select all the applications in the BizTalk Group and choose them to start (a great feature that for some unknown reason is forbidden and you can start only exactly one application at a time )  the pseudo code in the MMC is something like this:

Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer e = new Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer();
            e.ConnectionString = @"Data Source=" + dbServerName + ";Initial Catalog=BizTalkMgmtDb;Integrated Security=True";
 
            try
            {
                foreach (Microsoft.BizTalk.ExplorerOM.Application app in e.Applications)
                {
                    app.Start(Microsoft.BizTalk.ExplorerOM.ApplicationStartOption.StartAll);
                }
 
                e.SaveChanges();
            }
            catch (Exception ex)
            {
                throw ex;
            }

As you can see, all successfully started applications state has not been saved because that one application failed.


I think it's need to be like this:


            foreach (Microsoft.BizTalk.ExplorerOM.Application app in e.Applications)
            {
                try
                {
                    app.Start(Microsoft.BizTalk.ExplorerOM.ApplicationStartOption.StartAll);
                }
                catch (Exception ex)
                {
                    bool whatToDo = AskTheUserWhatToDo();
 
                    if (whatToDo)
                        throw ex;
                }
            }
 
            e.SaveChanges();

As an insight, the semi-unfriendly BizTalk 2006 Administration console GUI is not a direct effect of BizTalk deployment API's architecture - it's more like a half implementation in the MMC snap-in.

Tuesday, August 26, 2008

Unexpected disappearance of messages after executing BizTalk pipeline component

Here's another 'mysteries' behavior in BizTalk pipeline components:

If you're promoting a context property that only was 'GAC'd but haven't successfully deployed into BizTalkMgmtDb (by adding the BizTalkAssembly as a resource in BizTalk management console), at runtime the pipeline component will search the context schema generated class (see here) in the machine GAC and will promote the value as expected, BUT at the end of the Execute (IPipelineContext pContext, IBaseMessage pInMsg) method, BizTalk will 'freeze' like no message was submitted into the message-box by the pipeline. also there's no error messages in the event viewer. this is happens even if the promoted property is not used as the subscriber parameter.

It's not surprising that for a well working context property you must first deploy the property schema. the strange thing here is one, the way BizTalk pipeline components promoting values which is without any validation inside BizTalkMgmtDb schema tables. second, the unexpected disappearance of the message without any clue in the event viewer.

I guess this is one of the problems with the two management repositories of BizTalk artifacts: GAC and BizTalkMgmtDb database. for example: when you're looking for a IDocumentSpec object using GetDocumentSpecByName method - BizTalk will fetch the schema by executing a query against the database. but when working with a context property, in the pipeline perspective, even if it uses the previously generated schema class to get the name and namespace, the purpose is to add the value into the context property list with IBaseMessageContext.Promote method, so the pipeline is not looking inside the database to actually validate the context property existence and the pipeline assumes the developer is knowing what he is doing (yeah, right...). the problem is that afterwards, the pipeline is submits the message into the message box and then the routing engine is looking for a subscriber by executing T-SQL stored-procedure against the database, so you must have the context property inside the database tables.

Maybe in the next version we'll not have to manage artifacts in two places - till then, just be aware to deploy all the property schemas before running any pipeline component that uses them.

 
Copyright © 2007 | Diseñado por Blog and Web