Dynamic Data December preview context caching bug fix

Users of our recently released December preview of the new Dynamic Data feature in ASP.NET have noticed a pretty serious bug relating to foreign key column drop-downs. While this could be a breaking issue for many trying to test or adopt the new feature, I am glad to report that there is a workaround available.

This post talks about what the bug is and what steps are needed to resolve it. I am also attaching a zip file that you can simply unzip in the root of your Dynamic Data project (warning: this could overwrite customizations you have made to the project files. Read on to see what files are affected).

You can download the updated versions of the affected controls here (3 KB).

Bug symptoms

The bug affects the drop-down lists for foreign key relation columns as well foreign key filters. The problem occurs when you insert a new item into the parent table, then go to the child table and try to add a new entry, edit an existing one, or filter the table using the entry you added in the parent column. The drop-down list does not contain the newly added item and only restarting the entire app makes it appear (an analogous thing will happen if you remove an entry from the parent table).

This bug occurs because the Dynamic Data framework is trying to cache an instance of the DataContext object that represent the data model. The DataContext instance is something that should be instantiated, used to retrieve/submit information to the database, and then discard it. Dynamic Data holds on to it a bit longer than it should.

The solution

You can download the file mentioned at the beginning of this post to get the updated versions of the affected files. Simply unzip into the root of your Dynamic Data project. The included files are in C# but they should work even if your project is in VB.

The solution to the problem basically requires providing a new instance of the DataContext object to the controls responsible for rendering the drop-downs. This means you need to modify ForeignKey_Edit.ascx and FilterUserControl.ascx (both living in App_Shared\DynamicDataFields\ directory in the Dynamic Data project templates).

  • ForeignKey_Edit.ascx

    In the Page_Load method, replace the following line of code

     DropDownList1.DataSource = parentTable.Query;
    

    with this

     DropDownList1.DataSource = parentTable.DataContextProperty.GetValue(Activator.CreateInstance(DynamicDatabase.TheDatabase.CreateDataContext().GetType()), null);
    
  • FilterUserControl.ascx

    In the Page_Init method, replace the following line of code

     DropDownList1.DataSource = DataSource;
    

    with this

     var foreignKeyColumn = DynamicDatabase.TheDatabase.GetMetaTable(this.TableName).FindColumn(this.DataField) as DynamicMetaForeignKeyMember;
    if (foreignKeyColumn != null) {
        // only kick in if we are dealing with a foreign key column
        DropDownList1.DataSource = foreignKeyColumn.ParentMetaTable.DataContextProperty.GetValue(Activator.CreateInstance(DynamicDatabase.TheDatabase.CreateDataContext().GetType()), null);
    }
    else {
        DropDownList1.DataSource = DataSource;
    }
    

The new code is a bit ugly but it should work. Upcoming versions of Dynamic Data will not have this problem.

DataContextCachingFix_07_12_20.zip