Deployment Tools Foundation
What's New?
Overview > What's New? 2007-07-03

Highlights

Unfortunately, all these changes do mean that migrating tools and applications from the previous release can be a moderate amount of work.

Breaking Changes

For the first time since v1.0, this release contains some major breaking changes, due to a significant redesign and cleanup effort that has been a long time coming. The overall purpose of the changes is to bring the class libraries much closer to ship-quality.

Other Changes

Bugfixes

In addition to the extensive cleanup due to redesigns and unit tests, the following reported bugs have been fixed:

LINQ to MSI

You'll never want to write MSI SQL again!

Language INtegrated Query is a new feature in .NET Framework 3.5 and C# 3.0. Through a combination of intuitive language syntax and powerful query operations, LINQ provides a whole new level of productivity for working with data in your code. While the .NET Framework 3.5 provides LINQ capability for SQL databases and XML data, now you can write LINQ queries to fetch and even update data in MSI databases!

Look at the following example:

    var actions = from a in db.InstallExecuteSequences
                  join ca in db.CustomActions on a.Action equals ca.Action
                  where ca.Type == CustomActionTypes.Dll
                  orderby a.Sequence
                  select new {
                      Name = a.Action,
                      Target = ca.Target,
                      Sequence = a.Sequence };
          
    foreach (var a in actions)
    {
        Console.WriteLine(a);
    }
    
The query above gets automatically translated to MSI SQL:

    SELECT `InstallExecuteSequence`.`Action`, `CustomAction`.`Target`, `InstallExecuteSequence`.`Sequence` FROM `InstallExecuteSequence`, `CustomAction` WHERE `InstallExecuteSequence`.Action` = `CustomAction`.`Action` ORDER BY `InstallExecuteSequence`.`Sequence`

But the query is not executed until the foreach enumeration. Then records are fetched from the results incrementally as the enumeration progresses. The objects fetched are actually of an anonymous type created there in the query with exactly the desired fields. So the result of this code will be to print the Action, Target, and Sequence of all Type 1 custom actions.

The query functionality is currently limited by the capabilities of the MSI SQL engine. For example, a query can't use where (ca.Type & CustomActionTypes.Dll) != 0 because the bitwise-and operator is not supported by MSI SQL. The preview version of LINQ to MSI will throw an exception for cases like that, but the eventual goal is to have it automatically move the data and operation outside of MSI when necessary, so that any arbitrary expressions are supported in the query.

Note there are no MSI handles (or IDisposables) to worry about! Handles are all managed internally and closed deterministically. Also, with the entity object model for common tables, the compiler will tell you if you get a column name wrong or misspelled. The entity objects even support easy inserting, updating, and deleting (not shown here).

For more examples, see the LinqTest project in the source. More documentation is being written.

Obviously, LINQ to MSI requires .NET Framework 3.5. Everything else in DTF requires only .NET Framework 2.0.

Note: The LINQ functionality in this DTF release is of preview quality only and should not be used in production. While there are unit tests covering a wide variety of queries, using advanced queries outside what is covered by the tests is likely to result in unexpected exceptions, and retrieved data might possibly be incorrect or incomplete. An updated LINQ to MSI library is in development.