2016-04-05 14 views
0

döndüren uyumsuz arama gerçekleştirme MVVM Işık WPF uygulaması oluşturmak için Visual Studio 2015 ve Entity Framework 6 kullanıyorum.ObservableCollection

SearchEmployeesRelayCommand = new RelayCommand(SearchEmployees); 

Görünüm Modeli SearchEmployees yöntem aşağıdaki gibidir::

private BackgroundWorker _worker; 

public void SearchEmployees() 
{ 
    _worker = new BackgroundWorker(); // use this to show busy indicator 

    var dataService = new EmployeeDataService(); 
    _worker.DoWork += (o, ea) => 
    { 
     SearchResults = dataService.SearchEmployees(SelectedColumn, SearchValue); 
    }; 
    _worker.RunWorkerCompleted += (o, ea) => 
    { 
     IsSearching = false; 
    }; 

    IsSearching = true; 
    _worker.RunWorkerAsync(); 
} 

The kullanıcı Ara düğmesini tıkladığında, gör Model'in yapıcı böyle tanımlanmış bir RelayCommand çağırır veri hizmetinin arama yöntemi şöyle görünür:

public ObservableCollection<EmployeeViewModel> 
    SearchEmployees(string selectedColumn, string searchValue) 
{ 
    var paramEmployee = Expression.Parameter(typeof(Employee), "e"); 

    var comparison = Expression.Lambda<Func<Employee, bool>>(
     Expression.Equal(
      Expression.Property(paramEmployee, selectedColumn), 
      Expression.Constant(searchValue)), 
      paramEmployee).Compile(); 

    using (var context = new MyEntities()) 
    { 
     var query = (from e in context.Employees 
        .Where(comparison) 
        select new EmployeeViewModel 
        { 
         // Various EF model properties... 
        }); 
     return new ObservableCollection<EmployeeViewModel>(query); 
    } 
} 

yukarıdaki yöntem yapmaya çalışırsanız async veBu hata veriyor

return await new ObservableCollection<EmployeeViewModel>(query); 

: Böyle bir şey, bir ObservableCollection dönen eğer

'ObservableCollection' does not contain a definition for 'GetAwaiter' and no extension method 'GetAwaiter' accepting a first argument of type 'ObservableCollection' could be found (are you missing a using directive or an assembly reference?)

nasıl arama async yapabilirim? Teşekkürler.

Güncelleme: meşgul göstergesi çalışması için, ben bu değişikliği yapmak zorunda kaldı:

_worker.DoWork += async (o, ea) => 
{ 
    SearchResults = await dataService 
     .SearchEmployees(selectedColumnValue, SearchValue); 
    IsSearching = false; 
}; 

Ve tamamen _worker.RunWorkerCompleted blok kaldırıldı. Muhtemelen bunu yapmanın daha iyi bir yolu var, ama işte böyle çalıştım.

+1

Bu https://msdn.microsoft.com/en-us/library/hh191443.aspx – Will

cevap

2

Birkaç yaklaşım var. İlk olarak, veritabanı erişiminizi senkronize tutabilir ve sadece arka plan iş parçacığında çalıştırabilirsiniz. Task.RunBackgroundWorker için modern yerine geçer unutmayın (Ben blog series that draws parallels between the two var):

public async Task SearchEmployeesAsync() 
{ 
    var dataService = new EmployeeDataService(); 
    var selectedColumn = SelectedColumn; 
    var searchValue = searchValue; 

    IsSearching = true; 
    try 
    { 
    SearchResults = await Task.Run(() => dataService.SearchEmployees(selectedColumn, searchValue)); 
    } 
    finally 
    { 
    IsSearching = false; 
    } 
} 

Alternatif olarak, Ef6'yı kullandığınız beri, hiç arka plan iş parçacığı ile etrafında veritabanı sorgu asenkron ve uğraşmayın yapabilirsiniz:

public async Task<ObservableCollection<EmployeeViewModel>> 
    SearchEmployeesAsync(string selectedColumn, string searchValue) 
{ 
    var paramEmployee = Expression.Parameter(typeof(Employee), "e"); 
    var comparison = Expression.Lambda<Func<Employee, bool>>(
    Expression.Equal(
     Expression.Property(paramEmployee, selectedColumn), 
     Expression.Constant(searchValue)), 
     paramEmployee).Compile(); 

    using (var context = new MyEntities()) 
    { 
    var query = (from e in context.Employees 
       .Where(comparison) 
       select new EmployeeViewModel 
       { 
        // Various EF model properties... 
       }); 
    var data = await query.ToListAsync(); 
    return new ObservableCollection<EmployeeViewModel>(data); 
    } 
} 

public async Task SearchEmployeesAsync() 
{ 
    var dataService = new EmployeeDataService(); 
    IsSearching = true; 
    try 
    { 
    SearchResults = await dataService.SearchEmployeesAsync(SelectedColumn, SearchValue); 
    } 
    finally 
    { 
    IsSearching = false; 
    } 
} 

ürününü BackgroundWorker.DoWork eşzamansız yapmalısınız; Bu, "erken sona" neden olur ve onu istisnai olarak ele almaktan korur. BGW, async koduyla çalışmak için tasarlanmamıştı.

+0

'u okumanız gerekiyor, @StephenCleary. Query.ToListAsync() için bir neden var mı ve bundan sonra yeni bir 'ObservableCollection' alınıyor mu? – Alex

+0

Geri dönüş türü olmayan bir temsilci yöntem adı olan 'RelayCommand' ile ilgili sorun yaşıyorum. Bu satırdaki "void" den "Task" 'a dönüş türünü nasıl değiştirebilirim? SearchEmployeesRelayCommand = new RelayCommand (SearchEmployees); '? – Alex

+0

Bu sorunun "RelayCommand" ile bir değeri döndürdüğünü düşünüyorum: http://stackoverflow.com/questions/2240042/commanding-in-mvvm-wpf-how-to-return-a-value – Alex

İlgili konular