0

Ich implementiere einen einfachen Suchdienst und mehrere verschiedene Repositories werden darin eingefügt. Die Verwahrungsstellen haben eine Methode, die für ein Ausdruck wie so verwendet werden können:Ist es möglich, diesen LINQ-Ausdruck für Entity Framework zu vereinfachen?

public IEnumerable<T> Select(Expression<Func<T, bool>> predicate) 
    { 
     return _dbSet.Where(predicate).AsEnumerable().ToList(); 
    } 

Im Moment habe ich eine Aussage wie diese in meinem Suchdienst:

 searchResult.FoundCustomers = _customerRepository.Select(x => 
      x.FirstName.StartsWith(searchString) || 
      x.LastName.StartsWith(searchString) || 
      x.City.StartsWith(searchString) || 
      x.Country.StartsWith(searchString) || 
      x.Phone.StartsWith(searchString) || x.Phone.EndsWith(searchString)).ToList(); 

Gibt es eine Möglichkeit, die LINQ zu verbessern ? Die Wiederholungslosigkeit von searchString scheint unnötig, aber ich kenne LINQ noch nicht gut genug, um zu wissen, ob es einen Weg gibt, es zu vermeiden.

+0

http://stackoverflow.com/a/4430018/8155 aber es funktioniert nicht mit EF –

+0

@Jonesopolis Es ist wie seine 'Select' Methode sieht ruft' Where' : 'return _dbSet.Where' .. – Quantic

+0

@Quantic ack guten Ruf. Das ist irreführend. – Jonesopolis

Antwort

0

Zu Ihrer direkten Frage: Nein, Sie müssen die searchString mit jedem Feld vergleichen, das Sie in Ihre Suche aufnehmen möchten. Es gibt jedoch Möglichkeiten, die Erfahrung der Benutzer der Repositories zu verbessern.

Zum Beispiel könnten Sie eine Suchmethode in Ihrem Repository implementieren, dann müssten Sie in Ihrem Benutzercode nur diese Methode aufrufen. Sie könnten auch ein optionales Prädikat in Fällen Sie möchten die Ergebnisse weiter filtern, wie Sie jetzt tun:

public IEnumerable<T> Search(string searchString, Expression<Func<T, bool>> predicate) 
{ 
    var query = _dbSet.Where(x => 
     x.FirstName.StartsWith(searchString) || 
     // ... 
     x.Phone.EndsWith(searchString)); 

    if(null != predicate) 
    { 
     query = query.Where(predicate); 
    } 

    return query.ToList(); 
} 

Verbrauch:

var searchResults = _customerRepository.Search(searchString); 

Sie auch durchsuchbaren Felder mit benutzerdefinierten Attribute zuschreiben könnte, dann diejenigen verwenden Attribute zum dynamischen Erstellen der Abfrage. Dies erfordert eine gewisse Arbeit (deren Umsetzung besser einer anderen Frage überlassen wird), kann aber auf generische Weise erfolgen, so dass alle Ihre Repositories davon profitieren würden.

Anwendungsbeispiel:

public class Customer 
{ 
    [SearchField(Mode = SearchMode.StartsWith)] 
    public string FirstName { get; set; } 

    public string DontSearchMe { get; set; } 

    [SearchField(Mode = SearchMode.StartsWith | SearchMode.EndsWith)] 
    public string Phone { get; set; } 
} 

public abstract class Repository<T> 
{ 
    public IEnumerable<T> Search(string searchString) 
    { 
     var predicate = //generate predicate from attributed properties on class T and searchString parameter 

     return _context.Set<T>().Where(predicate).ToList(); 
    } 
} 
Verwandte Themen