Monday, July 09, 2007

Orcas and Entity Framework June 2007 CTPs - New Features

Despite Microsoft's deafening silence (so far) about the availability of the Orcas June 2007 CTP, a few pilgrims are spelunking the VM for new features. Folks are using Danny Simmons' new features list to test-drive the Entity Framework June 2007 CTP under the original Visual Web Developer Express (VWDX) June 2007 CTP as well as the full Orcas June 2007 CTP.

Update 7/10/2007: Here's the apparent explanation for Microsoft's deafening silence. The original Microsoft UK Visual Studio "Orcas" June 2007 CTP post reappeared this morning with the following caveat:

The Product Group have released an newer version of Visual Studio, but they aren't releasing it as a CTP. It is aimed at fixing a couple of problems for some targeted customers. The reality of this isn't tested or up to the quality of a proper CTP. You can still use this download, but it has some problems and it isn't supported for TFS. I would recommend waiting until Beta 2. Sorry for any confusion I have caused. [Spelling corrected.]

If the download page says it's a CTP and the four Readmes say it's a CTP, they released it as a CTP. The post's headline now calls it a "pre-CTP."

Tamir Khason of Microsoft Israel posted Orcas June CTP for limited beta is available on July 4, 2007 with this announcement:

After releasing June CTP of .NET framework 3.5, June CTP bits of Visual Studio 2008 (Team Suite and Visual Web Developer) are also ready for limited beta as Layout or VPC image.

and invited readers to contact him for downloading details.

Visual Basic 9.0 Language Features

VB MVP Bill McCarthy's What's new in June Orcas CTP for VB post lists the following new language features:

  • Lambda functions
  • Nullable types get ? shorthand for Nullable(Of ...) and operator elevation
  • Ternary If() function
  • JoinGroup By and other missing LINQ Standard Query Operators

Bill also mentions differences in C# 3.0 and VB 9.0 behavior in his Having fun with "Group-Ease", Change notification with Orcas data model and Keyed Anonymous types in VB9 posts.

VB 9.0 Lambda Functions and LINQ Method Call Syntax Issues

Online help's "Lambda Expressions [VB]" topic provides the following as a code example in the "Lambda Expressions in Queries" subtopic for method call query syntax:

Dim londonCusts As IQueryable(Of Customer) = _
    db.Customers.Where(Function(c) c.City = "London").Select(c)

If you create a new NorthwindDataContext that contains a Customer object and assign it to db, then add the above code to a Sub or Function, it won't compile. The c in the Select(c) selector isn't visible, which results in a "Name 'c' is not declared" error.

The following version with type inference compiles and returns the expected result to an iterator:

Dim londonCusts = _
    db.Customers.Where(Function(ByVal c) c.City = "London") _
                .Select(Function(ByVal c) c)

Notice that the ByVal directive is missing from the help topic's sample; if you don't type it, the compiler adds ByVal for you.

The preceding code seems absurdly verbose compared to the corresponding C# method call syntax:

var londonCusts = db.Customers.Where(c => c.City == "London")
                              .Select(c => c);

The following C# query chains an OrderBy lambda:

var londonCusts = db.Customers.Where(c => c.City == "London")
                              .OrderBy(c => c.ContactName)
                              .Select(c => c);

Here's the corresponding VB version:

Dim londonCusts = _
    db.Customers.Where(Function(ByVal c) c.City = "London") _
                .OrderBy(Function(ByVal c) c.ContactName)
                .Select(Function(ByVal c) c)

The problem with chaining the additional VB lambda expression is that you get the wrong IntelliSense's List Members collection (Equals, GetHashCode, GetType, ReferenceEquals and ToString instead of the Customer object's properties) for the intermediate OrderBy and other chained functions between Where and Select. C# IntelliSense has no such defect.

Join Operator Works But Union Method Is Still Broken

VB 9.0 finally acquired the Join operator, but the following code still returns the literal 'Customer' for every row, not a mix of 'Customer' and 'Supplier' values. I described this problem in my May 15, 2007 Changes Coming to LINQ for SQL post. Here's the VB code with Joins:

Dim sbQuery As New StringBuilder

Dim Query = ( _
From c In dcNwind.Customers _
Join s In dcNwind.Suppliers On c.City Equals s.City _
Select New With {c.City, c.CompanyName, .Type = "Customer"}) _
.Union( _
From c In dcNwind.Customers _
Join s In dcNwind.Suppliers On c.City Equals s.City _
Select New With {s.City, s.CompanyName, .Type = "Supplier"})

' Append list header
sbQuery.Append("City" + vbTab + "Company Name" + vbTab + "Type" + vbCrLf)
' Append query results
For Each u In Query
    sbQuery.Append(u.City + vbTab + u.CompanyName + vbTab + u.Type + vbCrLf)

Matt Warren said on May 15, 2007 in response to my Strange Behavior of LINQ Union Operator message in the LINQ Project General forum, "[T]here is a bug on how we treat literals in a union.  We are fixing it."

I plan to do more testing of JoinGroup By and other previously missing LINQ Standard Query Operators and will update this post accordingly.

Update 7/11/2007: Extensive tests of multiple Joins with typed and untyped DataSets indicate that it behaves as expected.

Julie Lerman Explores the Entity Framework's New Feature Set

MVP Julie Lerman provides in her illustrated Entity Framework, Some Before & After tidbits post:

  • Illustrated examples of fixes for the missing foreign key values,
  • Views and stored procedures now appear in the Entity Data Model Wizard
  • New support for stored procedures
  • Replacement of default constructors with Public Shared Function CreateObjectName functions.

Breaking Changes in .NET Fx Libraries (Update: 7/11/2007)

LINQ to SQL: INotifyPropertyChanged and Column properties have changed, which generates 100+ errors in small projects. You'll need to recreate your LINQ to SQL classes with the renamed LINQ to SQL Classes template.

LINQ to SQL: Jim Wooley reports in a comment that the System.Data.Linq.AttributeMappingSource and System.Data.Linq.XmlMappingSource classes have moved to System.Data.Linq.Mapping.AttributeMappingSource and System.Data.Linq.Mapping.XmlMappingSource respectively. [Note: MappingSource changed to AttributeMappingSource and XmlMapping changed to XmlMappingSource, and namespace prefixes added.]

LINQ to DataSet: The System.Data.DataTableExtensions namespace has moved from System.Data.Entities.dll to System.Data.DataSetExtensions.dll so you must change references.

LINQ to XML: Fixing "Could not load type 'System.Linq.Func`2' from assembly 'System.Core, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089'." exceptions requires adding a reference to System.Linq.DataSetExtensions.dll. This is probably a temporary expedient for the June 2007 CTP.

Problems with the Orcas June 2007 CTP

Julie reported problems running the Entity Framework June 2007 CTP and I encountered an issue running the extended Northwind database for the C# LINQ to Entity samples under the Orcas June 2007 CTP  in this thread in the ADO.NET Orcas forum.

If you've found and tested new language features (especially that support LINQ), please add a comment with a link to your post.


Jim Wooley said...

Another breaking LINQ to SQL change with this "CTP". The mapping attributes have changed their namespace as well. This will only require another Imports/using clause. This change allows them to set-up a heirarchy for System.Data.Linq.Mapping.AttributeMApping and .XmlMapping (going off of memory here)