locked
EF and databinding RRS feed

  • Question

  • Hi, I'm using WPF, and I'm trying to databind to Object Context and sort/filter the results. I've tried two approaches:

    -binding directly to context, data binding works fine (all context updates are automatically conveyed to UI), but I can't filter/sort results.

    -binding through CollectionViewSource to context gives me sorting/filtering capability, but removes connection to context. Changes in context don't seem to be automatically conveyed to UI.

    What is the proper way of solving this?

    Monday, May 9, 2011 11:30 PM

Answers

  • Hello IanThompson,

     

    Welcome to the Entity Framework Forum.

     

    According to your description, to databind to ObjectContext and sort/filter the results, we can use load and local methods. Load is a extension method on IQueryable that will cause the results of the query to be iterated, in EF this equates to materializing the results as objects and adding them to the DbContext in the Unchanged state. Of course you aren’t restricted to using the Load method to bring data into memory for databinding, any existing operations that cause objects to be materialized will also work (such as iterating results, ToList, ToArray, etc.).

     

    Because Load is an extension on IQueryable it can be called directly on a DbSet to load all items into memory or it can be used after LINQ operators. For example we could re-write our WPF code to only load Employees with an IsActive flag set to true:

     

    private void Window_Loaded(object sender, RoutedEventArgs e) 

         context.Employees.Where(e => e.IsActive).Load(); 
         this.DataContext = context.Employees.Local; 
    }

     

    The above example only works if we only ever bring active Employees into the context, but if other parts of the application need to bring inactive Employees into memory using the same context then we need a better way to filter. If you are using WPF then this functionality is already built in:

     

    private void Window_Loaded(object sender, RoutedEventArgs e) 

         context.Employees.Load(); 

         var view = new ListCollectionView(context.Employees.Local);
         view.Filter = e => ((Employee)e).IsActive;
         this.DataContext =  view;

    }

     

    I think you will be interested in the following articles, which are both about the related topic of yours:

     

    http://blogs.msdn.com/b/efdesign/archive/2010/09/08/data-binding-with-dbcontext.aspx

    http://blog.nicktown.info/2008/12/10/using-a-collectionviewsource-to-display-a-sorted-entitycollection.aspx

     

    I hope this can help you. Please feel free to tell me if I misunderstood you.

     

     

    Have a nice day,

     


    Jackie Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    • Proposed as answer by Jackie-Sun Tuesday, May 17, 2011 5:26 AM
    • Marked as answer by Jackie-Sun Friday, May 20, 2011 2:20 AM
    Wednesday, May 11, 2011 6:14 AM

All replies

  • Hello IanThompson,

     

    Welcome to the Entity Framework Forum.

     

    According to your description, to databind to ObjectContext and sort/filter the results, we can use load and local methods. Load is a extension method on IQueryable that will cause the results of the query to be iterated, in EF this equates to materializing the results as objects and adding them to the DbContext in the Unchanged state. Of course you aren’t restricted to using the Load method to bring data into memory for databinding, any existing operations that cause objects to be materialized will also work (such as iterating results, ToList, ToArray, etc.).

     

    Because Load is an extension on IQueryable it can be called directly on a DbSet to load all items into memory or it can be used after LINQ operators. For example we could re-write our WPF code to only load Employees with an IsActive flag set to true:

     

    private void Window_Loaded(object sender, RoutedEventArgs e) 

         context.Employees.Where(e => e.IsActive).Load(); 
         this.DataContext = context.Employees.Local; 
    }

     

    The above example only works if we only ever bring active Employees into the context, but if other parts of the application need to bring inactive Employees into memory using the same context then we need a better way to filter. If you are using WPF then this functionality is already built in:

     

    private void Window_Loaded(object sender, RoutedEventArgs e) 

         context.Employees.Load(); 

         var view = new ListCollectionView(context.Employees.Local);
         view.Filter = e => ((Employee)e).IsActive;
         this.DataContext =  view;

    }

     

    I think you will be interested in the following articles, which are both about the related topic of yours:

     

    http://blogs.msdn.com/b/efdesign/archive/2010/09/08/data-binding-with-dbcontext.aspx

    http://blog.nicktown.info/2008/12/10/using-a-collectionviewsource-to-display-a-sorted-entitycollection.aspx

     

    I hope this can help you. Please feel free to tell me if I misunderstood you.

     

     

    Have a nice day,

     


    Jackie Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    • Proposed as answer by Jackie-Sun Tuesday, May 17, 2011 5:26 AM
    • Marked as answer by Jackie-Sun Friday, May 20, 2011 2:20 AM
    Wednesday, May 11, 2011 6:14 AM
  • Say we have a DataContext bound to a DbSet's .Local as in your example. What if some entities are deleted from the database using a different context? How can we refresh the first context's .Local so that the DataContext no longer displays the entities that were deleted from the database?

    We don't want to Dispose and re-create the DataContext because that makes the UI look clumsy. (Plus, in my case, it takes about 30 seconds to build all the WPF controls for the entities.)

    Calling ListCollectionView.Refresh loads any entities that were added to the database, but it doesn't get rid of ones that were deleted.

    Thanks for your help.

    Thursday, June 30, 2011 3:06 AM