Skip to content
Matthieu MEZIL (MSFT) edited this page Jun 9, 2015 · 1 revision

In the MainWindow, you created a Refresh button in workshop 2.

This button works fine but, if MainWindowViewModel was using Customer class instead CustomerInfo one, it would not.

Why?
If you are familiar with Entity Framework, you probably know it.
WAQS, as Entity Framework, uses MergeOption.AppendOnly by default.

When WAQS loads an entity, WAQS tracks it on its cache which allows to just have to call SaveChangesAsync on your context.

Then, when WAQS got entities from server, you have 4 possible strategies:

  • MergeOption.AppendOnly: WAQS returns existing entities and new ones got from server.
  • MergeOption.OverwriteChanges: WAQS overwrites existing entities to return what you got from server.
  • MergeOption.PreserveChanges: WAQS overwrites existing entities except for changes and retrns them.
  • MergeOption.NoTracking: WAQS won't keep any references on your entities and just returns them as is.

So for example, you can use MergeOption.NoTracking on Employees query.

However, if you do so, the PropertyDescriptor we created in previous workshop won't work anymore because it applies only on the context entities.

So you can remove the _context.AddProperty in MainWindowViewModel constructor and replace the LoadEmployeesAsync method by this:

private async Task LoadEmployeesAsync()
{
    Employees = await _context.Employees.AsAsyncQueryable().Select(e => new Employee { Id = e.Id, FullName = e.FullName }).ExecuteAsync(MergeOption.NoTracking);
    foreach (var employee in Employees)
    {
        ((IDynamicType)employee).AddPropertyDescriptor(new DynamicType<Employee>.CustomPropertyDescriptor<bool>("IsSelected", 
            e => _selectedEmployees.Contains(e),
            (e, value) =>
            {
                if (value)
                {
                    _selectedEmployees.Add(e);
                }
                else
                {
                    _selectedEmployees.Remove(e);
                }
                Customers = null;
                LoadCustomersAsync().ConfigureAwait(true);
            }));
    }
}

The solution is available here.