Thursday, August 14, 2008

Upgrading Databound Projects to Entity Framework V1 RTM Doesn’t Expose DataSource’s 1:Many Associations

If you start your WinForm project with bound master-child[-grandchild] controls in a new project created with Visual Studio 2008 SP1 and using Entity Framework RTM as its data source, the nodes representing hierarchical 1:Many associations behave identically to those for typed DataSet and LINQ to LINQ to SQL data sources.

Update 8/17/2008: The “An error occurred while performing the drop” message disappeared when recreating the data sources a second time. However, data sources based on EntityCollections (one:many associations) still throw errors when attempting to set the BindingSource.DataMember with code and the DataMember property value choice appears as None in the BindingSource properties sheet.

Here’s a capture of the properties window with the missing DataMember property value choice for the ordersBindingSource as the DataSource property value of the order_DetailsBindingSource:

 

The DataSource code inserts the Order_Details DataMember value; you can’t select it or, in some cases, set it in code. For example,

ordersBindingSource = customerBindingSource;
ordersBindingSource.DataMember = "Orders";

throws a "Cannot bind to the property or column Address on the DataSource. Parameter name: dataMember" exception.

Updated 8/14/2008: Runtime exception details added.

For example, when you add to the Data Sources window a Customer EntitySet persisted to the Northwind.Customers table, you can drag the Customer.Orders node to the form to generate an orderBindingSource and bound orderDataGridView. In this case, orderBindingSource.DataSource = customerBindingSource and orderBindingSource.DataMember = “Orders”.

Links between the Customer EntitySet and Orders EntityCollection, BindingSources and DataGridViews are shown here in VS 2008 SP1 (Click image for full-size screen capture):

Similarly, dragging the Customer.Order.Order_Details node to the form generates order_DetailBindingSource.DataSource = orderBindingSource and order_DetailBindingSource.DataMember = “Order_Details”. Binding the two BindingSources to the associated EntityCollection synchronizes the orderDataGridView to the selected Customer entity and the order_DetailsDataGridView to the selected Order entity.

Problems with an Upgraded WinForms Project

Upgrading a pre-VS 2008 SP1 project to take advantage of EF v1’s new databinding enhancements by replacing the *.edmx file and its *.designer.cs or .vb partial class file with a new one requires you to:

  1. Delete the existing *.edmx file and its related files
  2. Delete the now-empty data sources from the Data Sources window
  3. Create a new *.edmx file in the EDM Designer
  4. Change the EDM partial class namespace from *Model to ProjectName
  5. Add new data sources to the Data Sources window
  6. Create new binding sources for child [and grandchild] DataGridView controls by dragging EntityCollection nodes to the form in design mode

Attempting step 6 for, as an example, the Customer.Orders EntityCollection, throws the following exception:

as noted in an update to my recent The Joys of Installing Visual Studio 2008 Service Pack 1 post.

Update 8/15/2008: Attempting to set the BindingSource at runtime with the following code:

order_DetailBindingSource = orderBindingSource;            order_DetailBindingSource.DataMember = "Order_Details";

throws a “The method or operation is not implemented” exception at runtime.

Most experienced .NET developers tend to avoid drag-and-drop databinding like the plague, but it’s handy for hooking up lightweight EntityCollections guaranteed to have a relatively few rows, such as line items of sales orders, invoices, or purchase orders. Line items must all be visible to create a meaningful UI for the user, while specific orders or groups of orders for a customer can be downloaded as required.

Having to perform major surgery on existing applications to take advantage of a new and needed feature is painful.

2 comments:

Jason Short - VistaDB said...

Is there no fix for this from MS? Is this just something that is broke in VS2008 SP1? I saw a lot of it doesn't work, but no work around... Is there one?

Roger Jennings (--rj) said...

@vistadb

Diego Vega of Microsoft's Entity Framework group was unable to reproduce the problems I encountered with installations on two development machines.

The issue with the missing DataMember picker remains open.

--rj