2016-04-19 7 views
2

Ich habe diese Methode:Lambda .Where Beschränkung auf Zeichenfolge

public List<object> GetThings(List<Guid> listOfGuids) 
{ 
    var query = serviceContext.Xrm.crmEntity; 
    bool anyTypeOfSearch = false; // use this to know if we have actually applied any search criteria. 

    if(listOfGuids != null && listOfGuids.Count > 0) 
    { 
     query = query.Where(x => listOfGuids.Contains(x.lgc_muncipalityid.Id)); 
     anyTypeOfSearch = true; 
    } 

    var result = new List<object>(); 
    if(anyTypeOfSearch) // instead of a variable here, can i check if there are any whereconditions applied to the query? 
     result = query 
      .Select(x => new SupplierSearchResultModel() 
      { 
       Id = x.Id, 
       Name = x.lgc_name, 
      }) 
      .ToList(); 

    LogMessage("GetThings.Query", <insert code to get query.Where condition tostring()>); 

    return result; 
} 

In dem realen Code gibt es verschiedene, wenn Strukturen mit .Where Bedingungen in ihnen und manchmal einen Aufruf diesen Code ohne Parameter erreichen können. In diesem Fall möchte ich die Abfrage nicht ausführen, da die Ergebnismenge sehr groß wäre. Daher möchte ich die Abfrage nur ausführen, wenn mindestens einmal die .Where() Bedingung angewendet wurde.

Jetzt ist meine Frage, kann ich eine Lambda-Abfrage-Variable für überprüfen, ob es .Where() Bedingungen angewendet hat, ohne eine externe bool wie ich bin?

Ein alternativer interessanter Verwendungspunkt wäre, wenn es eine Möglichkeit ist eine Art von query.Where().ToString() Methode zu erhalten, die zeigen würde, was Bedingungen angewandt werden, das im Fehlerfall eingeloggt sein könnte ...

+1

Normalerweise sollten Sie die Ergebnisse Ihrer Abfrage mit '.Take()' begrenzen, unabhängig von der Abfrage selbst. – Dbuggy

+0

Ich würde auch, aber da der Client die Daten nach der Spalte ihrer Wahl sortieren kann, würde ich nie wissen, ob ich eine ihrer ersten Zeilen entfernen oder zuletzt, ohne die Abfrage für jede Sortierung zu tun. Daher wähle ich eine etwas langsamere erste Suche für den Nutzen eines brauchbareren Ergebnisses. – JensB

+1

Yup hatte das gleiche Problem hinsichtlich der Sortierung. Wird verwaltet, damit die Sortierung serverseitig mit QueryExpression funktioniert. Das Sortieren nach Attributen in verbundenen Tabellen wurde jedoch nicht unterstützt (crm2011). Mußte leider nach dem Abfragen sortieren. Linq2Crm Anbieter vermisst viel Energie, die wir gewohnt sind. – Dbuggy

Antwort

3

Schnell & schmutzig, Wenn Sie sich nicht darum kümmern, ein schönes Ergebnis zu haben:

Aber es zeigt Ihnen nicht den Inhalt Ihrer Array-Parameter, obwohl.

bearbeiten Bessere Lösungen:

1) Was Sie suchen, ein Ausdruck Besucher ist. Eine Vorlage für das, was Sie want to do here, die dann wie verwendet werden soll:

LogMessage(query.ToPrettyString()); 

2) Denken Sie über einen Ausdruck query.Where(x=>x.member == GetSomething()) willst du es so gedruckt werden? Oder möchten Sie, dass das Ergebnis GetSomething() als Zeichenfolgenergebnis angezeigt wird? Wenn die zweite Lösung, dann können Sie das tun with this

+0

Ah, ich muss damit ertragen. Irgendwelche Alternativen, wenn ich paramaters will? Ziemlich wäre schön, aber nicht wirklich notwendig ..:) – JensB

+0

Ja, es gibt, aber sie erfordern ein wenig Berechnung, da es den Ausdrucksbaum durchqueren und jeden konstanten Knoten bewerten muss (es ist nicht völlig neutral in Bezug auf Leistungen, auch wenn es im Vergleich zu einem Netzwerkanruf vernachlässigbar ist) – Olivier

+1

Ich könnte Ihnen eine Probe finden, wenn Sie wünschen – Olivier

1

Sie können Ihre eigene Implementierung des ExpressionVisitor erstellen, um die Knoten des Ausdrucks zu durchlaufen. Sie können etwas tun:

public class WhereVisitor : ExpressionVisitor 
{ 
    private static bool _filter; 
    private static WhereVisitor _visitor = new WhereVisitor(); 

    private WhereVisitor() { } 

    public new static bool Visit(Expression expression) 
    { 
     _filter = false; 
     //Cast to ExpressionVisitor to use the default Visit and not our new one 
     ((ExpressionVisitor)_visitor).Visit(expression); 
     return _filter; 
    } 
    protected override Expression VisitMethodCall(MethodCallExpression node) 
    { 
     if (node.Method.Name == "Where") 
      _filter = true; 
     return base.VisitMethodCall(node); 
    } 
} 

Und es wie folgt verwenden:

bool containsWhere = WhereVisitor.Visit(query.Expression); 

Wenn Sie Sie können natürlich wollen die Besucher erweitern, um die Ausdrücke zu speichern, die eine Where Klausel enthalten, aber diese wird Ihnen nur sagen, ob es Where ist oder nicht.

Verwandte Themen