DataDirect’s Bruce acknowledged that from a productivity point of view, LINQ combined with its tooling gives .NET shops a productivity advantage that the Java community cannot match. He credits Microsoft’s ability to “package [productivity patterns and tooling] all up into something useful."

That said, he noted that LINQ is an unproven technology that is new to the market and said that he could not imagine anyone making corporate bets on LINQ just yet. “On the Java side, data access is rounded and stable. As a technology officer, it is an easier bet to make [on] what will reduce risks from a data perspective,” he explained. [Emphasis added.]

Apparently, Bruce isn't aware of LINQ to Objects, LINQ to XML, and the widening variety of current third-party LINQ implemetations and upcoming Microsoft versions:

Another example is XQuery, a language designed to query XML data. XQuery, he said, does a better job with data from many venues because of XML’s flexibility. By contrast, he claimed, the current implementation of LINQ is very targeted to what the developer is querying and the ability to “mash up data sources” has not been delivered yet, Bruce explained.

One of LINQ's strong points is it's "ability to 'mash up data sources'." Jon Udell's LINQ 101 post of September 28, 2005 demonstrated a three-way join between an XML data source and two CLR objects with the PDC 2005's LINQ preview. You can now join generic sequences from sets of in-memory objects (LINQ to Objects), XML documents, relational databases (LINQ to SQL and LINQ to Databases), and other domains with LINQ to SharePoint, LINQ to ActiveDirectory, LINQ to Amazon, and LINQ to Streams. If this capability for joining IEnumerable<T> sequences doesn't enable mashups, I don't know what does.

I find LINQ to XML to be a much more approachable and practical method for querying and composing XML Infosets than XQuery and/or XSLT. It's interesting that Microsoft is working on LINQ to Stored XML to supplement or replace its pre-XQuery 1.0 implementation for the SQL Server 2005+ xml data type.

Tuesday, January 29, 2008

Windows Communication Framework's WCF Service Configuration Editor lets you log SOAP request and response messages, as well as specify WCF service and client configuration declaratively. Newly created WCF services that use the HTTP transport specify the wsHttp binding, which applies SOAP message-level security with data encryption, digital signatures, and enables other WS-* security features.

WCF's service configuration is specified by the <system.serviceModel> section of the service project's Web.config (or App.config) file. Following are default service configuration values of Danny Sullivan's sample C# EntityBagSample.sln project from the NorthwindService.csproj project's Web.config file:

<system.serviceModel><services><servicename="NorthwindService.Service1"behaviorConfiguration="NorthwindService.Service1Behavior"><!-- Service Endpoints --><endpointaddress=""binding="wsHttpBinding"contract="NorthwindService.IService1" bindingConfiguration="wsHttp"><!-- Upon deployment, the following identity element should be removed or replaced to reflect the identity under which the deployed service runs. If removed, WCF will infer an appropriate identity automatically. --><identity><dnsvalue="localhost"/></identity></endpoint><endpointaddress="mex"binding="mexHttpBinding"contract="IMetadataExchange"/></service></services><bindings><wsHttpBinding><bindingname="wsHttp"maxReceivedMessageSize="50000000"maxBufferPoolSize="50000000"></binding></wsHttpBinding></bindings><behaviors><serviceBehaviors><behaviorname="NorthwindService.Service1Behavior"><!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --><serviceMetadatahttpGetEnabled="true"/><!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --><serviceDebugincludeExceptionDetailInFaults="true"/></behavior></serviceBehaviors></behaviors></system.serviceModel>

The basicHttp binding provides no message- or transport-level security by default, which enables comparing performance and message transport size of insecure and secure services.

Note: If you don't want to change the security model, go to step 5 to enable message logging.

It's a relatively simple process to change the transport by the following steps:

1. Open EntityBagSample.sln and choose Tools, WCF Configuration Editor, choose File, Open and navigate to and open the ...\entitybag\NorthwindService\Web.config file, and expand Services and Bindings nodes.

2. Click the Bindings node and the New Binding Configuration link to open the binding page. Type basicHttp as the Name and change the MaxBufferPoolSize, MaxBufferSize, and MaxReceivedMessageSize values to very large number, such as 50000000.

3. Click the top Endpoints node to open its Service EndPoint page, change its Name to NwBasicHttp or the like and select basicHttpBinding from the Binding dropdown list.

4. Open the BindingConfiguration list and choose the basicHttp configuration you created in step 2.

5. Click the Diagnostics node and click the Message Logging section's Enable Message Logging Link to turn Message Logging on and create an ...\entitybag\NorthwindService\Web_messages.svclog file. Optionally, click the Enable Log Auto Flush link to allow reading the log file while the service is running.

6. Click the Diagnostics node's Message Logging item to display the Message Logging page, set the LogEntireMessage and LogMessagesAtServiceLevel properties to True and increase the value of MaxSizeOfMessageToLog to a very large number.

<system.serviceModel><diagnostics><messageLogginglogEntireMessage="true"logMalformedMessages="true"logMessagesAtServiceLevel="true"logMessagesAtTransportLevel="true"maxSizeOfMessageToLog="50000000"/></diagnostics><services><servicebehaviorConfiguration="NorthwindService.Service1Behavior"name="NorthwindService.Service1"><endpointaddress=""binding="basicHttpBinding"bindingConfiguration="basicHttp"name="NwBasicHttpEP"contract="NorthwindService.IService1"><identity><dnsvalue="localhost"/></identity></endpoint><endpointaddress="mex"binding="mexHttpBinding"name="NwMexEP"contract="IMetadataExchange"/></service></services><bindings><basicHttpBinding><bindingname="basicHttp"maxBufferSize="50000000"maxBufferPoolSize="50000000"maxReceivedMessageSize="50000000"/></basicHttpBinding><wsHttpBinding><bindingname="wsHttp"maxBufferPoolSize="50000000"maxReceivedMessageSize="50000000"/></wsHttpBinding></bindings><behaviors><serviceBehaviors><behaviorname="NorthwindService.Service1Behavior"><!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --><serviceMetadatahttpGetEnabled="true"/><!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --><serviceDebugincludeExceptionDetailInFaults="true"/></behavior></serviceBehaviors></behaviors></system.serviceModel>

8. You must match the TestApp.csproj client project binding with that of the service, so choose File, Open and navigate to and open ...\entitybag\TestApp\App.config. Repeat step 2 for the Client node and step 3, except change the Endpoint name to basicHttpBinding_IService1.

10. You must associate files with the *.svclog extension with ServiceModel Trace Viewer tool (SvcTraceViewer.exe), so navigate to and right-click ...\entitybag\NorthwindService\Web_messages.svclog, choose Open With, click Browse, navigate to and double-click \Program Files\Microsoft SDKs\Windows\v6.0A\Bin\SvcTraceViewer.exe, and set it as the default program for opening .svclog files.

11. Run EntityBagSample.sln a couple of times to generate trace files, and then double click Web_messages.svclog to open the Trace Viewer. Click the Activity item to load the main pane, and then select a message. Here's the screen capture of a GetCustomerAndOrders SOAP request message:

12. Click the next message after a request message to review the SOAP response message to the GetCustomerAndOrders request, which includes the ContextSnapshot, shown here:

Click screen capture to open a full-size image.

Notice the 4-second delay between completion of the request and response messages. This delay is the reason that I downgraded the message-level security to basicHttp. I wanted to determine if encryption, signing, and other security overhead was responsible for what I considered to be a slow response time. It wasn't. Stay tuned for future posts on EntityBag performance.

to return a Customer EntityReference for each Order in the sequence. The obvious issue with the Include() method is that you lose compile-time checking of the LINQ to Entities expression by late-binding the related entity name.

However, the Entity Framework Sample Query Explorer project that installs with the Entity Framework Beta 3/Entity Framework Tools CTP 2 doesn't use the Include() method in the six sample queries (LinqToEntities70 to LinqToEntities76) of the Entity Framework Sample Query Explorer | Linq To Entities | Relationship and Navigation node.

to "Select a sequence of all the orders for a customer using Select." This query shouldn't work because it doesn't invoke the .Include("Orders") method for implicitly eager-loading each Customer entity's Orders EntitySet. (According to Julie Lerman, Danny Simmons considers the working query to be a bug.) The "correct" form of the query is:

Keyvan Nayyeri Builds a Blog Engine with ASP.NET MVC and LINQ

Microsoft released the first CTP of ASP.NET 3.5 Extensions and it includes ASP.NET MVC Framework as one of the main extensions for ASP.NET 3.5. In the first part of this article series about building a simple blog engine with ASP.NET MVC and LINQ, Keyvan introduces the MVC pattern, ASP.NET MVC Framework, and the fundamentals of a simple blogging engine.

In the second part of the article series about ASP.NET MVC Framework, Keyvan adds controllers to his blogging engine in order to describe how to use controllers in ASP.NET MVC and discusses some details related to controllers. He first discusses the concept of URL routing patterns and then explores the anatomy of a controller class. Finally, he examines how to implement the controllers in his sample blog application.

Stephen Toub Posts Essay on Recursion and Concurrency with PFx and PLINQ

The Parallel Programming with .NET blog's Recursion and Concurrency post by Stephen Toub of January 31, 2008 discusses scenarios for parallel processing of tree data structure traversal. Processing trees with multiple threads creates a number of issues, especially with recursive tree walking. The TaskParallel library simplifies walking the tree in parallel with a method such as this:

All in all, parallelism is a very interesting problem when it comes to recursion, and we hope the Parallel Extensions to the .NET Framework go a long way towards making the merging of these two concepts significantly easier.

Added: February 1, 2008

Bill Horst Tackles Left and Right Outer Joins with LINQ to Objects and LINQ to SQL

The VB team's Converting SQL to LINQ, Part 8: Left/Right Outer Join (Bill Horst) post of January 31, 2008 shows you how to emulate Left and Right Outer Joins with Group Join statements and Select clauses with nested IIf() function calls for LINQ to Objects. Substituting LINQ to SQL as the data source requires modification of the IIf() functions and an explicit cast to Nullable(Of OrderDate) for his Customer/Orders example.

The preceding query differs from the one I used with Northwind in the NwindEdmCS.sln sample code for my "Model Domain Objects with the Entity Framework" cover story for Visual Basic Magazine's March 2008 issue to populate the updatable orderDataGridView:

I discovered this syntax from the Entity Framework Sample Query Explorer’s LINQ to Entities | Relationship Navigation | Relationship Collection 1 (LinqToEntities70) query. It appears to me that the second Select() is necessary to sort the Orders. Here's the project's vanilla UI:

Click above capture for full-size image.

Added: January 31, 2008

Charlie Calvert Delivers a LINQ Expression Tree Tutorial

C# community evangelist Charlie Calvert's Expression Tree Basics post of January 31, 2008 demonstrates how to create an expression tree for the lambda function (a,b) => a + b, which adds two integers, a and b and returns the sum. Charlie explains that expression trees converts code into data, such as LINQ to SQL expression to T-SQL commands, and details the steps required to write and analyze a simple C# expression tree.

LINQ to SQL will be forced to open up their lighter weight model to third-party provider-writers.

According to Software Development Times magazine's Does .NET With LINQ Beat Java? article of January 30, 2008 by David Worthington [see above], Jonathan's "the program manager for .NET technology group at DataDirect Technologies, and formerly JDBC specification lead and architect for the Java platform at Sun."

So I thought something might have been lost in translation between Jonathan's Predictions for 2008? post of January 29, 2008 and Julie's copy. No such luck; Julie's quotes were identical, even to the missing the period in #2.

I can't fathom the first three prognostications, so here's my request for clarification:

2. Will "IBM file ... a set of established JDBC experts" (sounds impractical) or "draw [them] together? The latter sounds like herding cats to me. Will LINQ to Java have any relationship to IBM's pureQuery (formerly JLINQ)? JLINQ appeared to me (and others) to be a lightweight code generator for Java classes that's similar to LINQ to SQL without LINQ.

3. "Dynamic LINQ bridges [what] gap between compile-time type checking" and something else? In my view, you either have compile-time checking or you late-bind SQL strings, which is what LINQ eliminates with LINQ to SQL and LINQ to Entities. I'm confused.

4. "LINQ to SQL will be forced to open up their lighter weight model to third-party provider-writers" when hell freezes over. Microsoft is placing its database-agnostic bets on the Entity Framework and isn't about to devote the resources needed to write expression trees for PL/SQL or DB2 SQL dialects. Data Direct has announced plans to offer EntityClient-enabled ADO.NET data providers for the Entity Framework.

Elisa answers the question I posed last week about LINQ to Relational Data becoming LINQ to Entities' new name with her "Introducing LINQ to Relational Data" white paper of January 30, 2008. LINQ to Relational Data is a euphemism for two implementations of LINQ: LINQ to SQL and LINQ to Entities. Elisa provides a basic tutorial for creating a LINQ to SQL DataContext and Entity Data Model (EDM) with a LINQ to Entities query. She provides feature checklists to suggest when to use LINQ to SQL or the Entity Framework with LINQ to Entities.

The current ADO.NET Data Services drop returns exception messages and a stack trace to the client the service throws an exception. As Marcel says, this level of detail represents a potential security problem, so this will be changed in a future CTP.

If you're working with Danny Simmons' EntityBagSample.sln project, you might want to change the security model and enable message logging to test the effect of applying WS-* message-level security to your test project. My Logging EntityBag's SOAP Request and Response Messages post of January 29, 2008 shows you how to do this and how to associate Web_message.svclog log files with the ServiceModel Trace Viewer utility (SvcTraceViewer.Exe.)

Frans Bouma Reaches the Twelfth Step in His Quest for LINQ to LLBLGen Pro

In his Developing LINQ to LLBLGen Pro, part 12 post of January 29, 2008 Frans tackles Cast, OfType, Except, Intersect, and Single Standard Query Operators, examines the 'as' and 'let' keywords, and discusses LINQ to SQL issues with the T-SQL DISTINCT operator. Finally Frans described the work remaining in his LINQ to LLBLGen Pro implementation.

WPF in .NET 3.x doesn't have a built-in data-bindable grid control. If you haven't checked out third-party data grids or other data-bound controls for WPF, give Xceed's DataGrid for WPF Live Explorer demo a try.

Note: Xceed offers a free license for the DataGrid Express Edition, which requires free registration. The Professional Edition license is $495.

Anders walks us through the various C# 3.0 features and how they combine to create the subtle power that is LINQ (it's for a lot more than just relational databases, folks), but if you've seen his presentation on C# 3 at TechEd or PDC or any of the other conferences he's been to, you know how that story goes. The most interesting part of his presentation was a statement he made that I think has some interesting ramifications for the industry:

"I think that the taxonomies of programming languages are breaking down. I think that languages are fast becoming [an] amalgam. ... I think that in 10 years, there won't be any way to categorize languages as dynamic, static, procedural, object, and so on [paraphrased]."

Despite the lack of LINQ or Entity Framework content, Ted's literate and insightful review of the symposium's first day is a great read, especially if you're interested in dynamic languages.

Erik Meijer will present a Tuesday morning session on his Volta incubator project, but Volta's off-topic for this blog.

It's obvious why Erik is doing his talk at 9AM, because the man has far more energy than any human being has a right to have at this hour of the morning. Think of your hyperactive five-year-old nephew. On Christmas morning. And he's getting a G.I. Joe Super Bazooka With Real Bayonet Action(TM). Then you amp him up on caffeine and sugar. And speed.

Start with Erik's natural energy, throw in his excitement about Volta, compound in the fact that he's got the mic cranked up to 11 and I'm sitting in the front row and... well, this talk would wake the dead.

Erik demonstrates the same enthusiasm when speaking about LINQ or Haskell.

Ted also provides detailed coverage of Paul Vick's presentation: "He's talking on 'Bringing Scripting (Back) to Visual Basic', something that I can definitely agree with" and goes on to deplore the unjust denigration of VB by adherents of the "One Language God Intended":

Ted says that videos of the presentations should be available on Channel9 in about a week.

Update January 31, 2007: Ted's Highlights of the Lang.NET Symposium Day Three post attests to his almost-photographic memory, because his Mac froze when he hooked it up to a projector for a quick Scala presentation and his notes went bibi. (Serves you right for using a Mac, Ted.)

Danny Sullivan Posts Complete EntityBag Test Project with Bug Fix

Danny supplemented his earlier Perseus class library, which you need to implement his EntityBag class for service-enabling Entity Framework projects, with an EntityBagSample.sln project that you can download as Perseus-1.1.zip from his new Perseus: Entity Framework Entity Bag site on the MSDN Code Gallery. The new code, updated on January 27, 2008, fixes a minor bug "with connection strings that use Name to look up values from the config file."

Mike Pizzo to Present Programming LINQ and the Entity Framework Webcast on January 30, 2008

ADO.NET principal architect Mike Pizzo will present a one-hour live webcast, Programming LINQ and the Entity Framework, at 11:00 AM PST on Wednesday January 30, 2008. According to the webcast registration page:

Language Integrated Query (LINQ) introduces an exciting new way for applications to build strongly typed queries that are deeply integrated into the programming language. The ADO.NET Entity Framework allows applications and services to work in terms of an application-oriented Entity Data Model, decoupling the application's data model from the storage considerations of the relational schema. Join this webcast to see how these two technologies work together to change the way applications work with data.

Jim Wooley Updates His ThinqLinq Site

Jim spent Sunday, January 27, 2008, adding new features and posts to his LINQ-Powered ThinkLinq site. Check out:

By default WCF implements WS-* security with wsHttpBinding, which greatly increases SOAP message overhead, as Julie notes in her Testing out the EntityBag post of January 24, 2008. You can use the WCF Service Configuration Editor to change the service to basicHttpBinding, which defaults to clear text messages.

Suggestion: I believe it would behoove the ADO.NET Team to provide a simple reference project with a self-hosted service based on Northwind or AdventureWorksLT using the basicHttpBinding. This would save everyone that downloads the Perseus classes a substantial amount of time and guesswork on implementation details.

Questions: Will EFx become the official abbreviation for Entity Framework and LINQ to Entities be renamed LINQ to Relational Data? I doubt it.

Update 2 January 26, 2008: Diego says in two comments that Asad Khan didn't write the EDMX code generator (but didn't say who wrote it) and that LINQ to Relational Data is a generic term for LINQ implementations for relational data (i.e., LINQ to SQL and LINQ to Entities at the moment).

Sanjay's How does the ADO.NET Entity Designer generate code? of January 24, 2008 describes how the EntityModelCodeGenerator, which uses VS 2008's SingleFileGenerator extension mechanism, extracts the CSDL content from the EDMX file and generates code with the EntityClassGenerator.

Danny Simmons Wraps Up His EntityBag Sextet with the RelationshipEntry Story

EntityBag Part VI – RelationshipEntry of January 24, 2008 is the final installment of Danny's six-part EntyBag Extravaganza. RelationshipEntry is a DataContract-serializable class with eight DataMember properties:

RelationshipName

State

Role1

Key1

AddedEntityIndex1

AddedEntityIndex2

and two non-serializable properties

Entity1

Entity2

Constructor, ResolveEntityAndKeys, and Methods topics explain how the class is used.

The three class files (EntityBag.cs, ContextSnapshot.cs, and RelationshipEntry.cs) and required extension methods (UtilityExtensionMethods.cs) are in the PerseusEntity Framework Extension file that's described in the preceding "Diego Vega: ADO.NET Team Starts Entity Framework Portal on the MSDN Code Gallery Site" topic.

Added: January 25, 2008

Mike Taulty Minimizes LINQ to XML Code by Using the ReplaceWith() Method

The Pfx Team: Parallelizing LINQ Aggregate Queries with PLINQ

The Parallel Programming with .NET blog's Parallel Aggregations in PLINQ post of January 24, 2008 begins by describing how the Aggregate Standard Query Operator works, then discusses the general topic of parallel LINQ aggregation semantics, and identity issues that can cause the results of parallel and sequential aggregation to differ.

I was working with an Atom 1.0 document returned from an ADO.NET Data Service based on Northwind (what else?) when I ran across two anomalies in how LINQ to XML handles namespaces when composing XML Infosets with VB's literal XML or C#'s functional construction syntax.

VB MVP Bill McCarthy led me to an (apparently undocumented) workaround for a spurious xmlns="" namespace declaration, but I still haven't found the answer to preventing namespace declaration duplication with literal XML composition.

Julie Lerman: Those Who Forget the LinqDataSource Are Bound To Repeat Its Problems in the EntityDataSource

Julie Lerman recounts the problems that she's encountered with the LinqDataSource for LINQ to SQL, especially with lack of updatability when you specify a projection and return an anonymous type, and hopes they won't be repeated in the forthcoming EntityDataSource.

She also points out an anomalous exception when editing with Entity.Property/EntityReference pairs in combo boxes with StoreOriginalValuesInViewState set to True.

I'm not sanguine that the ADO.NET team can overcome these EntityDataSource hurdles by RTM.

Julie observes that the EntityDataSource "has been mentioned in the forums." Danny Simmons said:

While the LINQDataSource will not work with LINQ to Entities, we are working on an Entity Data Source which we expect to ship in v1 of the EF.

in answer to Blinky Bill's Informal List of Limitations entry of 1/3/2008 that spelled out some of the more serious issues with Entity Framework Beta 3. His complaints—together with Danny's replies—are well worth reading.

I would argue that making the ObjectStateManager serializable introduces significant issues long-term for n-tiered stacks. If it were serializable certain things would be easier, but it's somewhat like shooting yourself in the foot if you are building any kind of large-scale SOA system. You might take a look at my blog post: http://blogs.msdn.com/dsimmons/archive/2007/12/20/why-are-data-centric-web-services-so-hard-anyway.aspx That said, making n-tiered stacks easier to create is certainly an important topic we are giving a lot of thought to.

It's an interesting response in the light of Danny's current work on the EntityBag, no?

(My apologies to philosopher George Santayana,whose "Those who cannot remember the past are condemned to repeat it" warning comes from Reason in Common Sense, the first volume of his The Life of Reason quintet.)

Belgian developer Alexander Nowak's Unit testing ADO Entity Framework post of January 22, 2008 describes how he encountered "The specified metadata path is not valid" exceptions when attempting to unit test a sample Entity Framework Beta 3 project. The problem is related to issues with the design-time .edmx file and missing .ssdl, .msl, and .csdl from the specified MSTest folder that holds copies of the assembly and app.config or web.config files.

Alexander shows you how use the VS test environment's Deployment feature of the Rosario November 2007 CTP to add the missing metadata files to the appropriate MSTest folder.

Embedding the three metadata files in the assembly by the process Julie Lerman describes in her Embedding EDM schema files in Entity Framework Beta 3 post of December 14, 2007, should also solve the problem. Here's a brief excerpt from her detailed article on the topic.

Open the EDMX file in the design window and then you will see a new property in the property window called Metadata Artifact Processing. The default of this is "Copy to Output".

To get around a current known bug, build the project with the property set to "Copy to Output". Then change the Metadata Artifact Processing property to "Embed in Output Assembly". Eventually you won't need to build with Copy to Output first.

The EF won't have something like this built-in for v1, but we are looking hard at the topic for future releases. I'm not 100% certain we'll do this, since there are some serious issues when it comes to interoperability, etc. (as I've noted). I believe we made some major mistakes with the DataSet in this regard, and I don't want to repeat them.

Marcelo Lopez Ruiz Explains How to Use Service Operations with ADO.NET Data Services

Marcelo's Service Operations in ADO.NET Data Services post of January 21, 2008 explains how to set up ADO.NET Data Services with the RESTful equivalent of Web methods—Windows Communication Foundation (WCF) service operations that expose custom methods decorated with the [WebGet] attribute. The functions return an IQueryable<Model.Entity> or IEnumerable<Model.Entity> type, where Model is the name of the underlying Entity Data Model and Entity is the entity name, such as Customer[s].

The following WebDataService's CustomersInLondon() method returns an IQueryable<Model.Customer> to enumerate all Northwind Customers in London from this URL: http://localhost/WebDataService1.svc/CustomersInLondon.

Marcelo also explains how substituting [WebInvoke] for [WebGet] lets you pass parameters in the request body instead of the URL, [SingleResult] indicates that only a single instance is returned, and [MimeTypeAttribute] applies a particular MIME type, such as text/html, to the returned element(s).

I'm glad to see the ADO.NET Entity Framework team taking the pragmatic approach to Web service-enabling v1.0 with the serializable EntiyBag that Danny describes in his EntityBag Part I – Goals post of January 20, 2008.

The dual Web role application has been running in Microsoft's South Central US (San Antonio) data center since September 2009. I believe it is the oldest continuously running Windows Azure application.

About Me

I'm a Windows Azure Insider, a retired Windows Azure MVP, the principal developer for OakLeaf Systems and the author of 30+ books on Microsoft software. The books have more than 1.25 million English copies in print and have been translated into 20+ languages.

Full disclosure: I make part of my livelihood by writing about Microsoft products in books and for magazines. I regularly receive free evaluation software from Microsoft and press credentials for Microsoft Tech•Ed and PDC. I'm also a member of the Microsoft Partner Network.