2016-12-25 2 views
2

Ich habe eine Methode mit den folgenden Signaturen, die einen C# AusdruckNull Ausdruck mit dynamischen LINQ

Expression<Func<T, bool>> GetExpression<T>(IList<Filter> filters) 

dann den folgenden Code zurückgeben, die dynamischen LINQ verwendet

using (TestContext tEntities = new TestContext()) 
{ 
    var filterExp = Exp.ExpressionBuilder.GetExpression<Client>(filters); 
    var filteredCollection = tEntities.Client.Where(filterExp); 

    IQueryable<Client> queryResult; 
    if (filterExp == null) 
     queryResult = tEntities.Client; 
    else 
     queryResult = tEntities.Client.Where(filterExp); 
} 

Dies ist ein einfaches Szenario. Ich habe Abfragen, die 50 Zeilen lang sind manchmal mehr. Ich möchte vermeiden, den gleichen Code zweimal mit nur Unterschied zu haben, die where-Klausel verwendend.

Weiß jemand, ob ich etwas anderes erreiche?

from product in context.Product.Where(deleg) 
    .Include(x => x.Type) 
    .Include(x => x.Category) 
    .Include(x => x.WareHouse) 
    .Include(x => x.Photos) 
join f in context.Favorite on product.Id equals f.ProductFid into fg 
from fgi in fg.Where(f => f.UserFid == userId).DefaultIfEmpty() 
orderby product.Id descending 
select new ProductngDto() 
{ 
    ProductItem = product, 
    FavoriteId = fgi != null ? fgi.Id : (long?)null 
}).Skip(page * pageSize).Take(pageSize); 

Vielen Dank im Voraus

+3

Es ist nicht wirklich klar ist, was Sie fragen, aber ich denke, Sie wollen: 'IQueryable queryresult = tEntities.Client ; ' ' if (filterExp! = Null) {' ' queryResult = queryResult.Where (filterExp); ' '} ' – zaitsman

+0

@zaitsman Ich denke, er möchte nicht, dass sein Code mit nur einem kleinen Unterschied wiederholt wird die Where-Klausel. Dein Kommentar wird ihm sicherlich helfen. – Aamerallous

Antwort

2

Eines der schönen Dinge über IQueryable<T> und IEnumerable<T> ist die Tatsache, dass sie so abstrakt sind, können Sie sie leicht zusammen Kette. Eine Lösung könnte sein, Ihren Code wie folgt zu strukturieren:

using (TestContext tEntities = new TestContext()) 
{ 
    var filterExp = Exp.ExpressionBuilder.GetExpression<Client>(filters); 
    var filteredCollection = tEntities.Client.Where(filterExp); 

    IQueryable<Client> queryResult = tEntities.Client; 
    if (filterExp != null) 
    { 
     queryResult = queryResult.Where(filterExp); 
    } 
    //do something else with queryResult 
} 

Auf diese Weise können Sie weiterhin queryResult verwenden, ohne wissen zu müssen, oder sogar egal, ob oder nicht filterExp angewandt wurde.

Für das zweite Beispiel, es herumschlurfenden etwa wie folgt aussehen könnte:

var query = from p in context.Product 
         .Include(x => x.Type) 
         .Include(x => x.Category) 
         .Include(x => x.WareHouse) 
         .Include(x => x.Photos); 

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

query = from product in query 
     join f in context.Favorite on product.Id equals f.ProductFid into fg 
     from fgi in fg.Where(f => f.UserFid == userId).DefaultIfEmpty(); 
     orderby product.Id descending 
     select new ProductngDto() 
     { 
      ProductItem = product, 
      FavoriteId = fgi != null ? fgi.Id : (long?)null 
     }).Skip(page * pageSize).Take(pageSize); 

Eine weitere Option, die Sie haben, ist die filterExp für null zu überprüfen und eine „always true“ Lambda zuweisen. Wenn Sie die Methode GetExpression<T> steuern, können Sie sie als letzten Schritt hinzufügen. Wenn Sie es nicht kontrollieren, können Sie die Methoden, in denen Sie das Ergebnis verwenden, auf Null überprüfen.

Dies ermöglicht es Ihnen, Ihren Code ein wenig sauberer zu halten, aber der Kompromiss ist ein kleiner Leistungshit für die Bewertung des Lambda die ganze Zeit.

Je nachdem, wie Ihre Ausdrücke eingegeben werden, könnte dies so einfach sein wie:

if (filterExp == null) 
{ 
    filterExp = (_) => true; 
} 
+0

Vielen Dank für Ihre Antwort. Es ist eine akzeptable Lösung, aber wie würden Sie das anwenden, was Sie in der zweiten Abfrage vorgeschlagen haben, die ich oben hinzugefügt habe, und ist meine einfachste? – pantonis

+0

Ausgezeichneter Dank. Ich suchte nach dem immer wahren Zustand (1 = 1). – pantonis