Thursday, August 30, 2007

LINQ and Entity Framework Updates for 8/29/2007+

Video: ADO.NET Entity Framework - One Year Later

Pablo Castro, Britt Johnston and Michael Pizzo celebrate the first anniversary of the ADO.NET Entity Framework (EF) with a 34-minute Channel9 video segment: ADO.NET Entity Framework - One Year Later. The trio's first EF presentation was ADO.NET Entity Framework: What. How. Why., which was posted on September 1, 2006. (The August 29, 2007 posting date on the introduction page is a recent artifact; the 2006 date is from a Google cache of the page.)

Michael Pizzo, chief architect of the SQL Server Data Tools team that's in change of the EF project admits that the first release won't be fully persistence ignorant (03:30), but it's an improvement over previous CTPs and will be addressed in the next version. Pablo Castro gives a demonstration of the Entity Data Model (EDM) Designer starting at 21:00 and discusses how EF fits into the Data Tools team's Astoria project at 28:00. (Update 8/31/2007.)

WCF with Data Layer in VS 2008 Walkthrough by the VB Team

A Walkthrough of WCF Support in Visual Studio 2008 ordinarily would be off-topic for this post because it uses a strongly-type DataSet in its data layer. However, it's easy to substitute LINQ to SQL Table<TEntity> objects for the DataSet's DataTables. If you haven't created and consumed [Web] services with the Windows Communication Foundation (WCF), this post is a good introduction. (Update 8/31/2007.)

Entity Framework Beta 2 and EDM Tools CTP1 Docs Redux

You can read the online documentation for the Beta 2 and CTP1 bits here. The problem reported in the ADO.NET Entity Framework August 2007 CTP for VS 2008 Beta 2 Runtime and Tools Available post was a bad URL. Tommy from the Data Tools team confirmed in a comment that there were early problems opening the docs. (Update 8/31/2007.)

Julie Lerman and the Entity Framework's Former Span Keyword

Julie's 8/30/2007 Knocking off Danny Simmons Entity Framework Beta 2 List: #2: Span post announces that span has been replaced by the Include("AssociatedObjectName")[.Include("AssociatedObject2Name")...] ObjectContext method to return associated objects with the target object[s].

What disturbs me about this approach is introducing late-binding into the ordinarily early-bound (and thus compiler-checked) LINQ to Entities query.

Backstory: Matt Warren coined for Object Spaces the term span for a property that determines eager loading (pre-fetching) of associated objects. Matt says in his March 15, 2004 ObjectSpaces: Spanning the Matrix post:

ObjectSpaces has had the span parameter, and yes the name derives from my own ultra-nerdiness. It refers to the [linear] span of a [vector] space as used in linear algebra. Crack a book if you don’t believe me. [Clarifications and link added.]

(Updated 8/31/2007.)

Bart De Smet and New VB 9.0 Language Features

He's more than half way through this list of topics: 

(Updated 9/1/2007.)

Mike Taulty Organizes Links to his Recent Entity Framework Posts

His ADO.NET Entity Framework - Bringing Together A Few Previous Posts of 8/29/2007 provides a single page of links that's similar to my previous list but organized by topic.

Julie Lerman and the Entity Framework's New Complex Types Feature

Julie Lerman gives complex types a test drive with AdventureWorks LT in Knocking off Danny Simmons Entity Framework Beta 2 List: #1: Complex Types. Complex types combine related properties (such as streetAddress, city, state, postalCode and country) of a reference type (such as an order or customer) into a new type that becomes a single property (address) of the reference type.  Martin Fowler calls them value objects. He describes them as:

A small simple object, like money or a date range, whose equality isn't based on identity, ... instead two value objects are equal if all their fields are equal.

A general heuristic is that value objects should be entirely immutable. If you want to change a value object you should replace the object with a new one and not be allowed to update the values of the value object itself - updatable value objects lead to aliasing problems.

Value objects usually are represented in C# as a struct rather than a class. They have no identity beyond their values, so you can have multiple copies of them in memory. Danny Simmons discusses them in his 6/16/2007 Non-scalar Value Objects aka "Complex Types" post. My June 17, 2007 Entity Framework: Complex Types Redux in Beta 2 post discusses complex types in greater detail. (Updated 8/31/2007.)

Note: AdventureWorks' Person.Address and Sales.CustomerAddress types are reference types because their identity is the primary key of the persisted object.

Ben Hall on LINQ to SQL Files plus a LINQ in Action Review

For those new to SqlMetal.exe, Ben Hall describes the files it creates in his 8/20/2007 The power of SQLMetal post. His 8/28/2007 What are the files the Linq to SQL designer creates? post does the same for the O/R Designer.

Ben also gives a favorable review of the forthcoming LINQ in Action book by Fabrice Marguerie, Steve Eichert and Jim Wooley. It's currently available as an eBook in Manning's Early Access Program.

More SQL Server Compact Edition Beta 2 Releases

Now that LINQ to SQL semi-supports SQL Server Compact Edition, I'll be adding coverage of it to these weekly summaries. Microsoft India's SSCE team posted SQL Server Compact 3.5 Beta 2 Downloads on 8/30/2007 with links to the runtime, tools, and Books Online for the database engine and Microsoft Synchronization Services. For LINQ to SQL developers, SSCE's most important new feature is the timestamp (rowversion) data type.

Monday, August 27, 2007

ADO.NET Entity Framework August 2007 CTP for VS 2008 Beta 2 Runtime and Tools Available

The ADO.NET VNext team managed to deliver the August 2007 CTP with almost a week to spare. The ADO.NET Entity Framework Beta 2 page provides the ADO.NET Entity Framework (EF) Runtime, which is dependent on VS 2008 Beta 2 and is required for installing the EF Tools CTP below. Runtime changes listed are:

  • Events to customize code generation
  • Abstract types in EDM models
  • Complex types
  • <Using> support in metadata files
  • Entity key serialization
  • Increased persistence ignorance in entity data classes
  • Improved connection management in ObjectContext
  • Improved DataBinding usability
  • Metadata annotations
  • Better support for span over LINQ to Entities queries
  • Improvements to LINQ queries: additional canonical functions and automatic mapping from CLR functions to server functions
  • A new event for extensibility of SaveChanges
  • Usability and consistency improvements
  • Polymorphic results from stored procedures

Update 8/28/2007: Danny Simmons' early morning August CTP of the Entity Framework released post provides a brief summary of the each of the preceding changes.

You can install the runtime under Windows Server 2003, Windows Vista or Windows XP.

The ADO.Net Entity Framework Tools Aug 07 Community Technology Preview, a.k.a CTP1, which you must install after VS 2008 and ADO.NET EF Beta 2 runtime, lists the following updates:

Entity Designer (preview)

  • Generate a model from a database with the wizard and display it on the designer surface
  • Edit conceptual model properties (e.g. namespace, alias)
  • Layout and control visual aspects of the design surface and persist changes
  • Add, delete, and edit entities, scalar properties, associations, and inheritance
  • Automatic set management
  • Automatic navigation property management
  • Error reporting
  • Validate model and mappings using the Entity Framework Runtime
    Entity Mapping
  • View the mapping for a C-Side Entity or Association
  • Rename or delete C-Side objects without worrying about mapping
  • Map an EntityType to multiple tables
  • Apply multiple conditions to a table mapping
  • Map associations
  • Automatic generation of conditions and referential constraints on associations
  • Map an Entity hierarchy to a single table (TPH mapping)
  • Map an Entity hierarchy to multiple tables (TPT mapping)
    Entity Model Browser
  • Understand and visualize the model in a tree hierarchy
    Visual Studio Integration
  • Item template, model generation wizard, EdmxDeploy.exe, and Entity Framework validation on build
  • Update 8/28/2007: Julie Lerman's First look at the Entity Framework Designer post is a lavishly-illustrated tour of of the EDM designer, starting with adding the ADO.NET Entity Data Model template for the Northwind sample database to a WinForm.

    You can install the tools to VS 2008 Beta 2 Standard, Professional, Team Edition, and Express editions (C#, VB and Visual Web Developer) editions. 

    Following are some important issues from the Readme.html file:

    • 2.3.4 Cannot map entities to stored procedures
    • 2.3.6 Property window is missing many properties
    • 2.3.7 Wizard does not enable MARS when connecting to SQL Server 2005
    • 2.3.12 Editing .edmx file in the XML Editor is not supported
    • 2.3.14 F1 help does not work for Tools
    • 2.3.16 Unable to enter spaces in condition values
    • 2.3.19 In some cases, referential constraints are not created correctly

    Note: If your project isn't an ASP.NET website, ASP.NET web application, Console, WinForms, or Library, you must put the model in a separate class library project.

    Elisa Flasko's Entity Framework Beta 2 & the 1st Entity Framework Tools CTP Released! ADO.NET Team says that Docs and Samples for the Entity Framework Beta 2 can be found on MSDN and  CodePlex, respectively, but they weren't there as of 8/27/2007 18:00 PDT.

    Update 8/31/2007: You can read the online documentation for the Beta 2 and CTP1 bits here. The problem reported in the ADO.NET Entity Framework August 2007 CTP for VS 2008 Beta 2 Runtime and Tools Available post was a bad URL. Tommy from the Data Tools team confirmed in a comment that there were early problems opening the docs.

    Update 8/28/2007: The samples were available but docs were still missing at 06:00 PDT. Comments in the forum say the problem is intermittent and should be solved today, but my repeated attempts to open the docs failed.

    Mike Taulty has been working with an earlier internal drop and has just posted many helpful analyses of the new features:

    Note: The preceding list, which is in reverse chronological order, was current as of 8/27/2007 17:30 PDT.

    The new EDM Designer preview is finally here! Enjoy!

    Update 8/30/2007: Mike Taulty published a single-page of links to his posts: ADO.NET Entity Framework - Bringing Together A Few Previous Posts.

    Initial Reactions (8/28/2007)

    I haven't had a chance to spend much time with the new bits, but it's interesting to note that the three XML schema and mapping files (SSDL, MSL and CSDL) have coalesced into one EDMX file for the designer that splits into SSDL, MSL and CSDL files when you build the project.

    Support for SQL Server Compact Edition (SSCE) appears to be missing.

    Friday, August 24, 2007

    Clarification of the Object Tracking Problem with LINQ to SQL's Eager Loading Feature

    Scott Guthrie responded with the following comment to my suggestion (also in a comment) that he check my Eager Loading Appears to Cause LINQ to SQL Entity Table Problems post before writing his forthcoming post about Deferred/Eager Loading:

    Hi Roger,

    I'll go into more detail on lazy vs. eager loading in the post after next in my series.  Here are a few comments, though, that I posted in response to one of David's posts:

    In cases where the relationship between two entities is (n:1), LINQ to SQL does a JOIN as opposed to separate queries since these tend to be safe from a data explosion perspective.  

    In the case of a 1:n associations, LINQ to SQL only supports joining-in one 1:n association per query.

    So for example, if you wrote code like below:

        DataLoadOptions options = new DataLoadOptions();
        options.LoadWith<Product>(c => c.Category);
        options.LoadWith<Product>(c => c.OrderDetails);
        options.LoadWith<OrderDetail>(o => o.Order);
        db.LoadOptions = options;
        IEnumerable<Product> products = db.Products.ToList<Product>();

    You'd find that only 1 query is executed against the SQL database for everything (even though you are bringing back all of the Products and their associated Category and OrderDetail information).  This is because the product->category relationship is (n:1) and the OrderDetail->Order relationship is (n:1) and so both are automatically joined in.

    The reason the relationship in your blog post above is generating multiple queries is that you have two (1:n) relationship (Customers->Orders) and (Orders->OrderDetails).  If you just had one (1:n) relationship (Customer->Orders) or (Orders->OrderDetails) LINQ to SQL would optimize and grab it in one query (using a JOIN).  

    Hope this helps,

    Scott

    I noted in my post that one query per highest member of the object hierarchy probably wasn't a showstopper, but I'm reconsidering that conclusion. One of the primary goals of most data-oriented developers is to reduce server round trips for a particular activity to an absolute minimum. Three-level hierarchies are one of the most common object graphs you encounter in day-to-day development; think course:section:student or division:department:employee.

    I've updated my earlier post with the comment that while the TopLevelRows + 1 query count for eager loading of two 1:n joins appears to be by design, it's not a very good design.

    Suggested fix: Add a DataContext.AllowDataExplosions property that lets the developer enable an unlimited number of 1:n joins. Posted to Connect Feedback as Provide a DataContext.AllowDataExplosions Property for Eager Loading with Multiple 1:N Joins suggestion.

    The Real Problem

    The primary issue with LINQ to SQL's eager-loading loading feature seems to me to be the loss of object tracking when requerying the underlying tables. Deferred loading behaves in accordance with this statement in the "Object Identity" section LINQ to SQL: .NET Language-Integrated Query for Relational Data whitepaper by Dinesh Kulkarni, Luca Bolognese, Matt Warren, Anders Hejlsberg, and Kit George (March 2007):

    Of course, if the object requested by the query is easily identifiable by its primary key as one already retrieved no query is executed at all. The identity table acts as a cache storing all previously retrieved objects.

    Eager loading doesn't conform to this model.

    I plan to enhance the sample code with additional tests of the identity table after I finish my LINQ to SQL Stored Procedure Test Harness project which demonstrates some unexpected behavior and limitations when using stored procedures to hydrate LINQ to SQL object graphs.

    Stay tuned.

    Wednesday, August 22, 2007

    Eager Loading Appears to Cause LINQ to SQL Entity Table Problems

    Frans Bouma, David Hayden, Howard Richards and I have encountered an undesirable feature of LINQ to SQL having eager loading enabled with the DataContext.LoadOptions property value set to a collection of DataLoadOptions.LoadWith expressions. Using the Northwind Customers, Orders, and Order_Details tables as the source for test entity sets with 1:1 and 1:many associations, we all appear to believe the following DataContext.LoadOptions property value (or its C# equivalent) should load the Customer, Order, and Order_Detail entity sets with a single query, or at most a few queries:

    Dim dcNwind = New NorthwindDataContext
    Dim dlOptions As New DataLoadOptions
    dlOptions.LoadWith(Of Customer)(Function(c) c.Orders)
    dlOptions.LoadWith(Of Order)(Function(o) o.Order_Details)
    dcNwind.LoadOptions = dlOptions

    For example, Dave's test shows Frans Bouma's LLBLGen Pro loads all  Customer, Order, and Order_Detail entity sets with three queries. Dave's LINQ to SQL test required 40+ queries and my tests show 92 for the original 91 customers, but we all appear to agree that LINQ to SQL Beta 2 requires Customers.Count + 1 queries. The large number of queries is undesirable but not a showstopper.

    Howard Richards postulated a bug in this LINQ to SQL LoadOptions does not work for more than one level Feedback bug report:  LoadOptions doesn't populate EntitySets until the iterator encounters a request for a lower-level value and Microsoft finally acknowledged it's a bug.

    I don't find this to be an exact description of the real problem. The following iterator populates the associated EntitySets with 14 queries for 13 U.S. customers:

    Dim qryTest = From c In dcNwind.Customers _
                  Where c.Country = "USA" _
                  Select c

    For Each c In qryTest
        sbResult.Append(String.Format("Customer: {0}", _
            c.CompanyName) & vbCrLf)
    Next c

    The Real Problem

    I believe what Howard encountered was failure of the entity table/object tracker/identity management service to recognize the prior existence of the objects in memory, which caused the query pipeline to requery the database on successive LINQ query executions. This occurs despite the following statement in the "Object Identity" section LINQ to SQL: .NET Language-Integrated Query for Relational Data whitepaper:

    Of course, if the object requested by the query is easily identifiable by its primary key as one already retrieved no query is executed at all. The identity table acts as a cache storing all previously retrieved objects.

    All three objects meet the preceding requirement and, as to be demonstrated shortly, behave almost as expected with multiple queries when deferred loading is enabled. (The preceding quotation makes the single initial query unexpected.) Object tracking is enabled by default (DataContext.ObjectTrackingEnabled = True.)

    The LINQ to SQL Eager Versus Deferred Loading Test Harness project (EagerLoadingTestHarnessVB.sln) executes a set of queries with various DataContext.LoadOptions and DataContext.DeferredLoadingEnabled property value settings (see Figure 1.) Marking Deferred Loading Enabled, Set LoadOptions, Employee with Order, Shipper with Order or Project with Detail create a new DataContext object. Marking Show Query Result and clicking any of the buttons uses the same (current) DataContext object. Mark Show Query Result to replace the text box's T-SQL batch with the iterator's string output.

    The following table reports the number of queries for each of three different iterators (the LINQ query is identical in all cases):  


    Loading

    Query
    Get US Customers Get Orders Get Order_Details
    Deferred First 1 14 123
    Deferred Subsequent 1 1 1
    Eager First 14 14 14
    Eager Subsequent 14 14 14

    Requerying the database and reloading the objects into memory for each execution of every query against a DataContext.Table<TEntity> more than offsets any database load reduction from the initial eager loading. This problem, if confirmed by Microsoft and/or others, is a showstopper.

    You can run your own tests by downloading EagerLoadingTestHarnessVB.zip from the SkyDrive beta site. Right click the Zip file, choose Properties, click Unblock to eliminate the Untrusted security warning, and then unzip the files with Use Folder Names marked to a test folder. The NorthwindConnectionString in the app.config file expects to find a Northwind database in a local SQL Server 2005 Express instance (Data Source=.\SQLEXPRESS) and doesn't attach a Northwnd.mdf file. Make the necessary connection string modifications for your Northwind database setup and double-click EagerLoadingTestHarnessVB.sln.

    Please leave comments with questions or observations.

    Update 8/23/2007: Added as Connect bug 294781: LINQ to SQL Objects Eager Loaded with LoadOptions Aren't Recognized by Object Tracker, plus minor edits, updates and corrections.

    Update 8/24/2007: Microsoft was able to reproduce the bug. Added "The Real Problem" subhead for emphasis.

    Update 8/24/2007: TopObjectInHiearchy.Count + 1 queries for eager loading an object graph with two 1:n associations is by design, according to Scott Guthrie, but that's a bad design. This problem could turn out to be a showstopper for many developers and/or projects. See Clarification of the Object Tracking Problem with LINQ to SQL's Eager Loading Feature.

    LINQ and Entity Framework Updates for 8/22/2007

    Scott Guthrie and Rick Strahl on Dynamic LINQ to SQL Queries

    Scott continues his LINQ to SQL series with LINQ to SQL (Part 8 - Executing Custom SQL Expressions) that shows you how to use the DataContext.ExecuteQuery method and helper methods to fill Table<TEntity> objects with the appropriate subset of persisted data. Scott also describes how to use partial methods to persist updates with custom SQL statements. (Update 8/28/2007.)

    Rick's Dynamic Expressions in Linq to Sql is a highly detailed continuation of his earlier posts about issues with dynamic queries in LINQ to SQL. (Update 8/28/2007.)

    Mike Taulty covered Dynamic Expressions in his June, 2007 LINQ and Dynamic Queries, Bit More on Dynamic Queries, and More Dynamic Queries posts. (Update 8/28/2007.)

    Ian Cooper and Type Mocking for TDD

    Ian discusses Scott Bellware's disdain for type mocking in test-driven development (TDD) with strongly-typed languages, such as .NET, and (by inference) LINQ to SQL query results in his 8/24/2007 TypeMock, Static and Dynamically Typed Languages post. An example of type mocking is substituting an in-memory (LINQ to Objects) object graph for the DataContext to speed unit testing, a subject in which I have an interest. Ian came to this conclusion in his Being Ignorant with LINQ to SQL post:

    LINQ to SQL is usable with a TDD/DDD approach to development. Indeed the ability to swap between LINQ to Objects and LINQ to SQL promises to make much more of the code easily testable via unit tests than before.

    The preceding post refers to Eric Evans' Specification pattern (Domain-Driven Design, p. 224), which Ian adapted to dynamic LINQ queries in his earlier and very detailed Specifications in C# 3.0 post.  Ian provides the following short-form description of the Specification pattern:

    [A] specification is a pattern for expressing a rule which you want to use to test an object. A specification is ultimately used to separate two orthogonal concerns: testing objects and the objects themselves.

    If you're interested in metadata programming, TDD for LINQ to SQL, or both, don't miss this analysis. (Update 8/28/2007.)

    K. Scott Allen and Mocking the DataContext

    Scott's Trying Out Persistence Ignorance with LINQ (Part I) is the first of a series that explains how to "abstract the DataContext in a a stubable, fakeable, mockable fashion" to enable swapping DataContext and an "in memory data source" (A.K.A. LINQ to Objects).

    ADO.NET Entity Framework Runtime Beta 2 and Tools CTP1

    The ADO.NET VNext team managed to deliver the August 2007 CTP with almost a week to spare; see ADO.NET Entity Framework August 2007 CTP for VS 2008 Beta 2 Runtime and Tools Available, which includes abbreviated links to Mike Taulty's posts. The ADO.NET Entity Framework Beta 2 page provides the ADO.NET Entity Framework (EF) Runtime, which requires .NET Fx 3.5, and the ADO.Net Entity Framework Tools Aug 07 Community Technology Preview, a.k.a CTP1, which you must install after VS 2008 and ADO.NET EF Beta 2 runtime, finally delivers the EDM Designer preview! (Update 8/27/2007.)

    Mike Taulty and Entity Framework Beta 2 Runtime and Tools CTP1

    Mike Taulty has delivered a torrent of brief posts on new EF runtime and tools features.(Update 8/27/2007.)

    Beth Massi and Yet Another LINQ to SQL Video

    Beth said in her 8/27/2007 Channel 9 Interview - LINQ to SQL and the O/R Designer in VS 2008 post:

    I just posted another great interview on Channel 9 with Young Joo talking about LINQ to SQL and the new O/R Designer in Visual Studio 2008. He demos a typical business client-server scenario and shows how LINQ to SQL classes make it much easier to work with relational data in SQL Server 2005. Young also talks about architectures where he sees using LINQ to SQL having the most benefits.

    but she probably was drowned out by the clamor about the ADO.NET EF bits. (Update 8/27/2007.)

    The XML Team and the XML Schema Editor for VS 2008

    It's slightly off-topic, but the XML Team is Announcing CTP1 of the XML Schema Designer as of 8/27/2007. They say:

    XML Tools team has released the first CTP of the XML Schema Designer - a graphical tool for working with XML Schemas. The XML Schema Designer is integrated with Microsoft Visual Studio 2008 and the XML Editor to enable you to work with XML Schema definition language (XSD) schemas. If you have used the Visual Studio editor or notepad to edit your schemas, consider downloading this CTP and using it for editing your schema files. You can download it from Microsoft Downloads site. This CTP introduces the Schema Explorer - a tool that helps you navigate, search and work with schema sets. You can view a short video of the new functionality here

    Another post that might be lost in the ADO EF melee. (Update 8/27/2007.)

    Jim Wooley and Concurrency Checks with Stored Procedures for LINQ to SQL Updates

    Jim Wooley discusses one of the issues I encountered during my analysis of LINQ to SQL projects that use stored procedures for CRUD operations. Concurrency checking for UPDATEs and DELETIONs require either original object property values or adding a timestamp column. Adding a timestamp column will make your life much easier than writing stored procs, although you can use . See my earlier

    Scott Guthrie and LINQ to SQL Part 8

    LINQ to SQL (Part 8 - Executing Custom SQL Expressions) of 8/27/2007 shows you how to substitute your own SQL statements for stored procedures or statements generated from LINQ queries translated by expression trees. This post explains how to use the DataContext.ExecuteQuery<T> method with a custom SQL statement to populate objects.

    Julie Lerman and Named Anonymous Types in LINQ Queries

    Julie investigates the benefits of identifying LINQ's Select expression explicitly with its own name in Specifying named types in LINQ Queries of 8/27/2007.

    Jim Wooley and ThinkLinq

    Jim updated his ThinkLinq demo website for VS 2008 Beta 2 on 8/28/2007. The details are at ThinkLinq demo app updated for Beta 2.

    Bart De Smet and VB 9.0

    Bart promises to start a series of posts on VB 9.0 in his 8/22/2007 Visual Basic 9.0 Feature Focus - Introduction post. Topics include:

    Bart usually keeps his promises.

    Mike Taulty and the Entity Framework

    Mike's authored an improved set of Entity Framework diagrams and more detailed descriptions EF capabilities of in his 8/21/2007 Entity Framework - Various Models to Query, Various Means to Querying post. Mike Taulty Compares LINQ to SQL and LINQ to Entities discusses Mike's first shot at diagramming the EF.

    There's still no news from the ADO.NET EF team when the Beta 2 update will be available or when we can expect some documentation from them.

    Joe Albahari and LINQPad

    Joe Albahari, co-author of the forthcoming C# 3.0 in a Nutshell, has released the Beta 2 version of his beta LINQPad application that lets you write LINQ to Objects, LINQ to SQL, and LINQ to XML queries in a text box and then execute them as if they were included in code. LINQPad also has features that overlap SQL Server Management Studio [Express].

    Ben Hall and SQL Metal

    Ben Hall's 8/20/2007 The power of SQLMetal post provides a guided tour of SqlMetal.exe's command-line syntax. The O/R Designer finally uses SqlMetal.exe in Beta 2. You'll also need to use SqlMetal.exe in lieu of the O/R Designer if you're working with SQL Server Compact Edition (SSCE), as noted in LINQ to SQL to Support SQL Server Compact Edition.

    Beth Massi and LINQ to SQL Videos

    Beth reports that "Bill Burrows has done it again and created a series of videos to help get you started with LINQ to SQL in Visual Basic!"

    She also offers advice on Converting VS 2005 Projects to VS 2008 - Enabling LINQ.

    Scott Guthrie and LINQ to SQL Part 7

    LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) continues the series with a lengthy and detailed description of how to use stored procedures for inserts, updates, and deletions. (Updated 7/23/2007.)

    Microsoft Research and DryadLINQ

    Microsoft Research says this about their Dryad Project, which has goals and techniques in common with Google's MapReduce programming model.

    Dryad is an infrastructure which allows a programmer to use the resources of a computer cluster or a data center for running data-parallel programs. A Dryad programmer can use thousands of machines, each of them with multiple processors or cores, without knowing anything about concurrent programming.

    DryadLINQ is a subproject with the following objectives:

    The goal of DryadLINQ is to make distributed computing on large compute cluster simple, simple enough for ordinary programmers. DryadLINQ combines two important pieces of Microsoft technology: the Dryad distributed execution engine and the .NET Language Integrated Query (LINQ). Dryad enables reliable, distributed computing on thousands of servers for large-scale data parallel applications; LINQ enables the developers to write and debug their applications in a SQL-like query language, with the entire .NET library at their disposal and in the familiar environment of Visual Studio. This combination has produced a simple, powerful, and elegant programming environment for writing large-scale data parallel applications running on large PC clusters.

    DryadLINQ appears to be a competitor to Yahoo's Pig (for Hadoop) and Google's Sawzall query languages. Greg Linden analyzes these two in his Yahoo Pig and Google Sawzall post. (The Dryad: Distributed Data-Parallel Programs from Sequential Building Blocks research paper mentions LINQ only in passing.)

    Will DryadLINQ morph to LINQ for Dryad when productized? Who knows. (Updated 7/23/2007. Thanks to Mary Jo Foley for the heads-up.)

    OakLeaf and LINQ to SQL Issues

    I built a simple test harness to see if I could verify an issue raised in a comment by Frans Bouma to my LINQ to SQL Query Execution with LoadOptions Specified post. David Hayden's LINQ To SQL - Query Tuning Appears To Break Down In *More Advanced* Scenarios post reports on the issue he discussed in the context of the LINQ to SQL Visualizer.

    My test harness confirmed the current requirement for one query per Customer object to return associated Order and Order_Detail objects. Apparently LLBLGen Pro's can do the same with three queries for all Customer, Order, and Order_Detail objects. It also confirmed the symptoms of the (finally-admitted) bug reported by Howard Richards in this LINQ bug - just me? LINQ Project General forum post, but not the bug itself.

    However, I'm finding what appears to be an even worse problem: The entity table doesn't work as expected when you specify a DataContext.LoadOptions property value to eager-load Customer objects' associated Order and Order_Detail objects. Clicking the Get US Customer button runs 14 T-SQL queries to load 13 Customers and associated objects, which should now be in the entity table (and in memory). However, clicking Get Orders and Get Order_Details on the same DataContext instance issues the same 14 T-SQL queries. This problem doesn't occur with deferred loading enabled.

    You can expect a detailed post and a downloadable copy of the project for this test harness later today:

    I'm working on a similar test harness to demonstrate LINQ to SQL's lack of support for substituting stored procedures for T-SQL statements to populate DataContext.Table<TEntity> objects.

    Update 8/22/2007, 6:00 PM PDT: The post with the downloadable code is Eager Loading Appears to Cause LINQ to SQL Entity Table Problems.

    Why I Use Desktop Apps

    Tuesday, August 21, 2007

    SQL Server Compact Edition Blogstorm

    Coinciding with the landing of Hurricane Dean on the unfortunate city of Chetumal, located on the Yucatan Penninsula's Atlantic coast, the SQL Server Compact Edition (SSCE) team launched a mini-storm of blog posts, to wit:

    LINQ with SQL Server Compact (a.k.a. DLINQ with SQL CE) by Pragya Agarwal provides sketchy details for using SqlMetal.exe to create partial classes for SSCE databases. As noted in my July 29, 2007 LINQ to SQL to Support SQL Server Compact Edition post, LINQ to SQL graphical O/R Designer doesn't support SSCE.

    Sync Services for ADO.NET and SQL Server Compact Presentation by SSCE Program Steve Lasker provides links to three PowerPoint presentations about occasionally connected services (OCS): Tech Ed US '07 DAT 325- Synchronization Options for SQL Server Compact, Optimizing Online, Enabling Offline with SQL Server Compact and Sync Services for ADO.NET, and Logical Queuing Demo. Logical queuing combines SSCE's Sync Services and MSMQ or a queued WCF channel to sync updates when the back end is ready to accept them.

    Article updated on Code Project by Rafik Robeal points to a version of Take Data Offline Using Microsoft Synchronization Services for ADO.NET from the CodeProject site that's updated to Beta 2.

    Rafik's August 17, 2007 Updates, updates, updates … post summarizes the significant changes to Sync Services from Beta 1 to Beta 2. Rafik also updated his Sync Services demos.

    Chetumal side story:I've had a continuing interest in Mayan archeology since my college days at UC Berkeley. In 1992, I took a month off and flew my 1955 Piper PA23-150 Apache (2061P) down the east coast of Mexico with stops at Vera Cruz, Villahermosa (Olmec, not Maya), Palenque, and Merida, where I put up at the Casa del Balam hotel. (Merida has an international-class airport). At the time, students at the Universidad Autónoma de Yucatán were staging a rambunctuous sit-in across the street from the hotel, reminiscent of the uprisings during UC Berkeley's Free Speech movement. I also enjoy middle-eastern food and was surprised to find several excellent Lebanese restaurants in Merida, which provided relief from the relatively simple Yucatecan cuisine. A fantastic beach at Progresso is just a few km from Merida.

    I made side-trips to Dzibilchaltun (for a swim in the Xlacah cenote -- swimming is now discouraged), Chichen Itza, Uxmal (plus Sayil, Kabah, Labna and Xlapak), Cancun (a.k.a. Puerto Juarez, which was then undergoing a major construction boom), Tulum, Coba, and Yaxchilán, along with Isla Mujeres and Cozumel for skin diving. All the major Mayan sites have nearby airports at least 1 km in length. A trip down south down the Atlantic coast took me over the Mesoamerican Barrier Reef System (including the Arrecifes de Sian Ka'an), the second-longest barrier reef in the world to Chetumal. There wasn't much of interest in the city, but the food was good. I doubt if any area near Chetumal is over 10 meters above sea level, so a storm surge of 4 to 6 meters undoubtedly wreaked a great deal of havoc in the town of about 130,000 souls.

    Monday, August 20, 2007

    LINQ to SQL Query Execution with LoadOptions Specified

    David Hayden, a Florida .NET developer and C# MVP, posted an update to his LINQ To SQL Debugger Visualizer in Visual Studio 2008 Has Limited Value - LINQ To SQL Tutorials item this morning. In LINQ To SQL Debugger Visualizer Revisited - Same Concerns Better UI :), David says:

    In the previous post I mentioned some concerns I have with the LINQ To SQL Debugger Visualizer in that the query it displays is not the whole story. ...

    Turns out I wasn't even using the Debugger Visualizer - DOH! Here is the real LINQ To SQL Debugger Visualizer, which is a separate download.

    He goes on to say:

    So, the debugger visualizer is much easier to work with than I previously mentioned in the earlier post, but it still suggests only 1 query will be executed when in actuality it will execute 40+ queries to the database using the following code in beta 2:

    using (NorthwindDataContext = new NorthwindDataContext())
    {           
        DataLoadOptions options = new DataLoadOptions();    
        options.LoadWith<Customer>(c => c.Orders);
        options.LoadWith<Order>(o => o.Order_Details);    
        var query = from c in context.Customers select c;
    }

    I talked more about that in the previous post mentioned above. A little deceptive if you ask me, but still useful in other ways. [Emphasis added.]

    The problem is that David omitted this critical instruction prior to executing the LINQ query:

    NorthwindDataContext.LoadOptions = options;

    to attach the DataLoadOptions to the NorthwindDataContext.

    Further, his last instruction specifies context instead of NorthwindDataContext from his using expression. 

    Update: 8/20/2007 12:00 PM PDT

    David added the missing instruction but didn't correct the DataContext name. (See his comment.)

    David's query returns EntitySets of Order and Order_Detail objects for each Customer object. When corrected, the preceding query with an iterator executes this query to obtain the Customer objects:

    SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], 
      [t0].[ContactTitle], [t0].[Address], [t0].[City], [t0].[Region], 
      [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax]
    FROM [dbo].[Customers] AS [t0]
    

    It is the preceding query that appears in the Query Visualizer. It's not reasonable to expect the Query Visualizer to interrogate the DataContext.LoadOptions property value and iterate over the DataLoadOptions collection to see what objects are being eader-loaded. 

    The SELECT query is followed by this query for each of the 91 Customer objects to retrieve the EntitySets, as you would expect:

    exec sp_executesql N'SELECT [t0].[OrderID], [t0].[CustomerID], 
      [t0].[EmployeeID], [t0].[OrderDate], [t0].[RequiredDate], 
      [t0].[ShippedDate], [t0].[ShipVia], [t0].[Freight], [t0].[ShipName], 
      [t0].[ShipAddress], [t0].[ShipCity], [t0].[ShipRegion], 
      [t0].[ShipPostalCode], [t0].[ShipCountry], [t1].[OrderID] AS [OrderID2], 
      [t1].[ProductID], [t1].[UnitPrice], [t1].[Quantity], [t1].[Discount], (
        SELECT COUNT(*)
        FROM [dbo].[Order Details] AS [t2]
        WHERE [t2].[OrderID] = [t0].[OrderID]
        ) AS [count]
        FROM [dbo].[Orders] AS [t0]
        LEFT OUTER JOIN [dbo].[Order Details] AS [t1] 
          ON [t1].[OrderID] = [t0].[OrderID]
        WHERE [t0].[CustomerID] = @x1
        ORDER BY [t0].[OrderID], [t1].[ProductID]',N'@x1 nchar(5)',@x1=N'ALFKI'
    

    I find it hard to believe that any developer who deliberately adds code to eager-load 830 Order and 2155 Order_Detail objects would be deceived into believing that a simple SELECT query against the Customers table would retrieve 2,985 rows from two other tables in the database.

    I'm also not sure why David mentioned 41+ queries in his post. It's obvious that 91 queries are required to hydrate the EntitySets for 91 Customer objects.

    End Update

    I tested Beta 2's updated DataContext.LoadOptions feature recently and found that it behaved as advertised with a similar query against the Orders entity set to prevent lazy loading of EntityRef objects:

    public partial class NorthwindDataContext {
        partial void OnCreated() {
            DataLoadOptions dlOrder = new DataLoadOptions();
            dlOrder.LoadWith<Order>(o => o.Customer);
            dlOrder.LoadWith<Order>(o => o.Employee);
            dlOrder.LoadWith<Order>(o => o.Shipper);
            this.LoadOptions = dlOrder;
        }
    }

    (I was testing the LinqDataSource with a bound GridView, so I had to add the LoadOptions collection in the OnCreated event handler of a separate partial class file.)

    With GridView.PageSize = 15, loading the first page generates two queries:

    SELECT COUNT(*) AS [value]
    FROM [dbo].[Orders] AS [t0]
    LEFT OUTER JOIN [dbo].[Customers] AS [t1] 
        ON [t1].[CustomerID] = [t0].[CustomerID]
    LEFT OUTER JOIN [dbo].[Employees] AS [t2] 
        ON [t2].[EmployeeID] = [t0].[EmployeeID]
    LEFT OUTER JOIN [dbo].[Shippers] AS [t3] ON [t3].[ShipperID] = [t0].[ShipVia]
    
    exec sp_executesql N'SELECT TOP 15 [t7].[OrderID], [t7].[CustomerID], 
      [t7].[EmployeeID], [t7].[OrderDate], [t7].[RequiredDate], 
      [t7].[ShippedDate], [t7].[ShipVia], [t7].[Freight], [t7].[ShipName], 
      [t7].[ShipAddress], [t7].[ShipCity], [t7].[ShipRegion], 
      [t7].[ShipPostalCode], [t7].[ShipCountry], [t7].[test], 
      [t7].[CustomerID2], [t7].[CompanyName], [t7].[ContactName], 
      [t7].[ContactTitle], [t7].[Address], [t7].[City], [t7].[Region], 
      [t7].[PostalCode], [t7].[Country], [t7].[Phone], [t7].[Fax], [t7].[test2],
      [t7].[EmployeeID2], [t7].[LastName], [t7].[FirstName], [t7].[Title], 
      [t7].[TitleOfCourtesy], [t7].[BirthDate], [t7].[HireDate], 
      [t7].[Address2], [t7].[City2], [t7].[Region2], [t7].[PostalCode2], 
      [t7].[Country2], [t7].[HomePhone], [t7].[Extension], [t7].[Notes], 
      [t7].[ReportsTo], [t7].[test3], [t7].[ShipperID], [t7].[CompanyName2], 
      [t7].[Phone2]
    FROM (
      SELECT ROW_NUMBER() OVER (ORDER BY [t0].[OrderID], [t0].[CustomerID], 
        [t0].[EmployeeID], [t0].[OrderDate], [t0].[RequiredDate], 
        [t0].[ShippedDate], [t0].[ShipVia], [t0].[Freight], [t0].[ShipName], 
        [t0].[ShipAddress], [t0].[ShipCity], [t0].[ShipRegion], 
        [t0].[ShipPostalCode], [t0].[ShipCountry], [t2].[test], 
        [t2].[CustomerID], [t2].[CompanyName], [t2].[ContactName], 
        [t2].[ContactTitle], [t2].[Address], [t2].[City], [t2].[Region], 
        [t2].[PostalCode], [t2].[Country], [t2].[Phone], [t2].[Fax], 
        [t4].[test], [t4].[EmployeeID], [t4].[LastName], [t4].[FirstName], 
        [t4].[Title], [t4].[TitleOfCourtesy], [t4].[BirthDate], [t4].[HireDate], 
        [t4].[Address], [t4].[City], [t4].[Region], [t4].[PostalCode], 
        [t4].[Country], [t4].[HomePhone], [t4].[Extension], [t4].[ReportsTo], 
        [t6].[test], [t6].[ShipperID], [t6].[CompanyName], [t6].[Phone]) 
      AS [ROW_NUMBER], 
        [t0].[OrderID], [t0].[CustomerID], [t0].[EmployeeID], [t0].[OrderDate], 
        [t0].[RequiredDate], [t0].[ShippedDate], [t0].[ShipVia], [t0].[Freight], 
        [t0].[ShipName], [t0].[ShipAddress], [t0].[ShipCity], [t0].[ShipRegion], 
        [t0].[ShipPostalCode], [t0].[ShipCountry], [t2].[test], 
        [t2].[CustomerID] AS [CustomerID2], [t2].[CompanyName], 
        [t2].[ContactName], [t2].[ContactTitle], [t2].[Address], [t2].[City], 
        [t2].[Region], [t2].[PostalCode], [t2].[Country], [t2].[Phone], 
        [t2].[Fax], [t4].[test] AS [test2], [t4].[EmployeeID] AS [EmployeeID2], 
        [t4].[LastName], [t4].[FirstName], [t4].[Title], [t4].[TitleOfCourtesy], 
        [t4].[BirthDate], [t4].[HireDate], [t4].[Address] AS [Address2], 
        [t4].[City] AS [City2], [t4].[Region] AS [Region2], 
        [t4].[PostalCode] AS [PostalCode2], [t4].[Country] AS [Country2], 
        [t4].[HomePhone], [t4].[Extension], [t4].[Notes], [t4].[ReportsTo], 
        [t6].[test] AS [test3], [t6].[ShipperID], 
        [t6].[CompanyName] AS [CompanyName2], [t6].[Phone] AS [Phone2]
      FROM [dbo].[Orders] AS [t0]
        LEFT OUTER JOIN (
          SELECT 1 AS [test], [t1].[CustomerID], [t1].[CompanyName], 
            [t1].[ContactName], [t1].[ContactTitle], [t1].[Address], 
            [t1].[City], [t1].[Region], [t1].[PostalCode], [t1].[Country], 
            [t1].[Phone], [t1].[Fax]
          FROM [dbo].[Customers] AS [t1]
            ) AS [t2] ON [t2].[CustomerID] = [t0].[CustomerID]
        LEFT OUTER JOIN (
          SELECT 1 AS [test], [t3].[EmployeeID], [t3].[LastName], 
            [t3].[FirstName], [t3].[Title], [t3].[TitleOfCourtesy], 
            [t3].[BirthDate], [t3].[HireDate], [t3].[Address], [t3].[City], 
            [t3].[Region], [t3].[PostalCode], [t3].[Country], [t3].[HomePhone], 
            [t3].[Extension], [t3].[Notes], [t3].[ReportsTo]
          FROM [dbo].[Employees] AS [t3]
            ) AS [t4] ON [t4].[EmployeeID] = [t0].[EmployeeID]
        LEFT OUTER JOIN (
            SELECT 1 AS [test], [t5].[ShipperID], [t5].[CompanyName], 
              [t5].[Phone]
            FROM [dbo].[Shippers] AS [t5]
            ) AS [t6] ON [t6].[ShipperID] = [t0].[ShipVia]
        ) AS [t7]
    WHERE [t7].[ROW_NUMBER] > @p0',N'@p0 int',@p0=15

    I probably wouldn't have gone through the trouble to post this rejoinder if:

    1. David hadn't stated that 40+ queries were required to execute his query.
    2. The bogus issue he raised was the result of a missing instruction not expecting the Query Visualizer to evaluate the DataContext.LoadOptions property value for eager-loading instructions. 
    3. He hadn't used the term "deceptive" in describing the Query Visualizer's failure to detect them.
    4. He had comments enabled on his blog.
    5. The ADO.NET team hadn't gone through an extreme effort to build the required T-SQL batch in the query pipeline's expression tree.

    Wednesday, August 15, 2007

    LINQ Updates for 8/15/2007

    Beth Massi has produced the first two videos in a series featuring VB 9.0 and LINQ: #1 - How Do I: Get Started with LINQ? (00:09:14) and #2 - How Do I: Perform Group and Aggregate Queries? (00:17:22).

    Bart de Smet has released LINQ to SharePoint Alpha 0.2.3 updated for VS 2008 Beta 2 with a number of new features and fixes.

    Richard Hale Shaw apparently gave a rip-snorting "Moving Up to C# 3.0 and LINQ: What's In It For Me?" presentation of at Julie Lerman's Vermont .NET User Group last night.

    Ben Hall, a UK developer, has been investigating LINQ to SQL lately and has interesting posts about partial methods, the LinqDataSource, and DataContext object.

    C# MVP Rick Strahl has his doubts about the viability of LINQ to SQL as a data access layer (DAL) for business objects because of problems with LINQ to SQL and attaching Entities (8/12/2007). He also wonders about LINQ to SQL and Dynamic Queries and Expressions? (8/13/2007), but solves the problems with persisting changes to detached entities with a timestamp field in LINQ to SQL and Disconnected Entities Follow-up (8/15/2007). I'll be writing more about LINQ to SQL DALs for business objects in the near future.

    Update 9/16/2007: C# MVP David Hayden is more optimistic about the future of LINQ to SQL as a DAL than Rick Strahl. He's been writing a series of posts about LINQ to SQL during the past three weeks. His recent emphasis is on replacing dynamic T-SQL queries with stored procedures. Here's the list in chronological order:

    I've run into a corner using the LinqDataSource control with a stored procedure as the DataContext's data source. More follows about the problem in a separate post tomorrow.

    Scott Guthrie has posted LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures), which describes the process of dragging SELECT * FROM TableName stored procs from Server Explorer and dropping them on one of the O/R Designer's entity class widgets to specify the type of the ISingleResult<EntityType> returned by the function that executes the stored proc. ISingleResult<EntityType> implements IEnumerable<T> but not ITable<TEntity>. Scott applies the ToList() method to bind ISingleResult<EntityType> to a read-only GridView control. What's required is a way to take advantage of partial methods to return an ITable<EntityType> for binding to a LinqDataControl and enable editing in ASP.NET GridView or DetailsView controls.

    Tuesday, August 14, 2007

    Erik Meijer to Demo Volta for the First Time at OOPSLA 2007

    Erik Meijer, the "Creator of LINQ," will make four—count 'em, four!—presentations to the ACM SIGPLAN International Conference on Object-Oriented Programming, Systems, Languages and Applications (OOPSLA) 2007 conference in Montréal, Canada, from October 21 through 24, 2007.

    Democratizing the Cloud with Volta (Demo)

    Volta is a Tesla incubator project that's charged with development of LINQ 2.0. According to Erik, "We've made very good progress in turning ideas into working code. In particular, the declarative tier splitting is really cool."

    This is the first scheduled public demo of Volta's tool-assisted approach to dividing client/server applications into n-tier projects automatically. Here's the latest abstract from Erik's updated paper:

    Programming distributed data-intensive web and mobile applications is gratuitously hard. As the world is moving more and more towards the software as services model, we have to come up with practical solutions to build distributed systems that are approachable for normal programmers. Just like Visual Basic democratized programming Windows by removing much of the boilerplate, such as message pumps and window handles, that contributed more to the problem than to the solution, we propose a toolkit of language extensions, APIs, and tools that do the same for web programming. As a result, ordinary programmers can concentrate on the essential aspects of building distributed and mobile applications such as partitioning and flowing code and data across tiers, deployment, security, etc. without getting bogged down in low level details.

    Here's a link to Erik's earlier "LINQ 2.0: Democratizing the Cloud" paper, as well as Mary Jo Foley's August 8 2007 A (Microsoft) Code Name a Day: Volta and April 23, 2007 Volta: Microsoft’s dev platform in the Cloud? posts. Here's my original post March 16, 2007 "LINQ 2.0" in Early Returns from QCon 2007, London and subsequent May 18, 2007 Erik Meijer and LINQ 2.0 - Round 2 and August 2, 2007 QCon 2007 and Erik Meijer Coming to San Francisco November 7 - 9 items.

    Confessions of a Used Computer Language Salesman (Essay)

    Erik wrote "Confessions of a Used Programming Language Salesman: Getting the Masses Hooked on Haskell" for The 11th ACM SIGPLAN International Conference on Functional Programming (ICFP 2006), held in Portland, Oregon on September 18-20, 2006, but his PDF file doesn't carry the ICFP copyright. Here's the OOPSLA abstract:

    Programmers in the real world wrestle every day to overcome the impedance mismatch between relational data, objects, and XML. For the past ten years we have been working on solving this problem by applying principles from functional programming, in particular monads and comprehensions. By viewing data as monads and formulating queries as comprehensions, it becomes possible to unify the three data models and their corresponding programming languages instead of considering each as a separate special case. To bring these theoretical ideas within the reach of mainstream programmers, we have worked tirelessly on transferring functional programming technology from pure Haskell, via Comega to the upcoming versions of C# 3.0 and Visual Basic 9 and the LINQ framework. Functional programming has finally reached the masses, except that it is called Visual Basic instead of Lisp, ML, or Haskell!

    I first wrote about this paper in my May 16, 2006 Erik Meijer Promotes LINQ at Expo-C 2006 post, but this might be the paper's first formal presentation.

    Lost in translation: Formalizing proposed extensions to C# (Paper)

    Erik's giving this paper in conjunction with Gavin Bierman (Microsoft Research Cambridge) and Mads Torgersen. Here's the OOPSLA abstract:

    Current real-world software applications typically involve heavy use of relational and XML data and their query languages. Unfortunately object-oriented languages and database query languages are based on different semantic foundations and optimization strategies. The resulting "ROX impedance mismatch" currently makes life very difficult for developers. Microsoft Corporation is currently developing extensions to the .NET framework to facilitate easier processing of non-object-oriented data models. Part of this project (known as "LINQ") includes various extensions to the .NET languages to leverage this support. In this paper we consider the current proposals for C# 3.0, the next version of the C# programming language. We give both an informal introduction to the new language features, and also a precise formal account by defining a translation from C# 3.0 to C# 2.0. This translation also demonstrates how these language extensions do not require any changes to the underlying CLR.

    Apparently, Gavin's still at work on the paper, but here's a link to an earlier related presentation, "Formalizing and extending C] type inference (Work in progress)" that Gavin presented at the 2007 International Workshop on Foundations and Developments of Object-Oriented Languages (FOOL/WOOD '07).

    LINQ from the Source (Demo)

    Erik and Ted Neward (Ted Neward and Associates) will join in delivering this 3.5-hour demo that Erik says will be an "introduction to the various LINQ parts with lots of code samples and many questions from the audience. It's great to see that LINQ is catching on!" Here's the OOPSLA abstract:

    Language Integrated Query (LINQ) is one of the hot technologies in the next version of Visual Studio. In this session, hosted by one of the designers of VB9, C# 3.0, LINQ to Objects, LINQ to XML, and LINQ to SQL, we will drill down into all the gory technical details behind LINQ, as well as its practical applicability to modern development projects, from large-scale enterprise systems to "tiny webapps on a big database" projects. This is a unique opportunity to get a first hand account of this new technology, the design process, and historical context.

    Ted Neward is the author of the infamous "Object/Relational Mapping is the VietNam of Computer Science" essay.

    Update 8/15/2007: Unrelated links have moved to LINQ Updates for 8/15/2007.

    Wednesday, August 08, 2007

    Restore a Missing LinqDataSource Control to Your Toolbox and Data Source Wizard

    I have two conventional (DVD) VS 2008 Team System Beta 2 installations on two relatively recent computers. One is installed in its own partition on a Dell server running Windows Vista Ultimate. The other runs under a Virtual Server 2005 R2 SP1 VM on a Gateway dual-core client that uses Windows Server 2003 R2 SP1 as the host OS and Windows Vista Ultimate as the guest OS. The Gateway has 4 GB RAM with 1 GB devoted to the Vista VM.

    When I moved my day-to-day development from the Dell Server to the VM, I was surprised to find the ASP.NET LinqDataSource control missing from the Configure Data Source Wizard's first dialog. I checked the Toolbox's Data section and found it missing there, too. So I right-clicked the Toolbox and choose Reset from the context menu, expecting that to materialize the missing control in both locations. No luck.

    I searched on LinqDataControl missing and found a hit in a comment to Scott Guthrie's LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) post by Greg McCarty dated today (August 8, 2007):

    Beta2 doesn't seem to have the LinqDataSource control in any toolbox? What am I missing?

    and an earlier comment of July 29, 2007 by Steve to Scott's July 26, 2007 VS 2008 and .NET 3.5 Beta 2 Released post:

    LinqDataSource was missing from Toolbox after install but was available via intellisence. I got it into the Toolbox by Resetting the Toolbox.

    It's clear that others were having the problem, too, but Steve's solution didn't work for me.

    Finally, I right-clicked the the Toolbox and clicked Choose Items to open the Choose Toolbox Items dialog. Sure enough, the LinqDataSource checkbox was empty:

    Click image for full-size capture from Windows Live SkyDrive Beta.

    I had not made any modifications to the Toolbox, so the LinqDataSource checkbox must have been empty after Setup completed. Both machines had been running Orcas June 2007 CTP, which I removed and then ran devenv /reset on both machines before starting VS 2008, as recommended by Scott Guthrie (see comments).

    Scott Guthrie provides a clue why some installs might have missing LinqDataSource controls in the Toolbox and Wizard, but it doesn't apply to my case. In addition, selecting Reset from the Toolbox's context menu should have added the LinqDataSource. It did for Steve, but not for me. Any ideas?

    Update 8/9/2007: Response to Scott Guthrie's comment re devenv /reset.