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:
- Delete the existing *.edmx file and its related files
- Delete the now-empty data sources from the Data Sources window
- Create a new *.edmx file in the EDM Designer
- Change the EDM partial class namespace from *Model to ProjectName
- Add new data sources to the Data Sources window
- 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.