2009-08-19 14 views
43

ausgegeben und zurückgegeben wird. Hier ist das Szenario: Ich habe eine Reihe verschiedener Repository-Klassen, die jeweils einen isolierten Datenkontext oder einen gemeinsamen Kontext verwenden können. In den Fällen, in denen ein isolierter Kontext verwendet wird, möchte ich der Basisklasse eine Methode hinzufügen, die es mir erlaubt, das Lambda als Parameter anzugeben, diesen Ausdruck durch den isolierten Kontext des ausgewählten Repositorys ausführen und ein IQueryable-Ergebnis zurückgeben . Wie würde die Methodensignatur aussehen und wie soll der Ausdruck an den Kontext übergeben werden?LINQ: Lambda-Ausdruck als Parameter übergeben, der von der Methode

Ich brauche die Lösung so allgemein wie möglich zu sein, da jedes mögliche Modellobjekt/Tabelle verwendet werden könnte. Hier

ist im Grunde, was ich zu tun Suche:

IAssetRepository repo = new AssetRepository(true); // true indicates isolated context 
var results = repo.ExecuteInContext<SomeType>(SomeTable.Where(x => 
               x.SomeProp.Equals(SomeValue))); 

Antwort

57

Etwas wie folgt aus:

public IEnumerable<T> ExecuteInContext<T>(
    Expression<Func<T,bool>> predicate) 
{ 
    ... // do your stuff 
    //eg 
    Table<T> t = GetTable<T>(); 
    return t.Where(predicate); 
} 

oder

public IEnumerable<T> ExecuteInContext<T>(
    IQueryable<T> src, Expression<Func<T,bool>> predicate) 
{ 
    return src.Where(predicate); 
} 

Verbrauch:

var r = repo.ExecuteInContext<SomeType>( 
      x => x.SomeProp.Equals(Somevalue)); 

oder

var r = repo.ExecuteInContext(GetTable<T>(), 
      x => x.SomeProp.Equals(Somevalue)); 

Annahmen:

  1. Tabelle kann von T abgeleitet werden, sonst müssen Sie auch die Quelle zu übergeben.
  2. Sie wissen, wie Sie den Prädikatausdruck bei Bedarf ändern können.
+0

Parameter zu übergeben, wenn Ihr erster Vorschlag versucht, ich einen Fehler der Tabelle t zusammengestellt = GetTable (); line: T muss ein Referenztyp sein, um es als Parameter zu verwenden –

+0

vergiss es, ich habe es. benötigt, um "where T: class" am Ende der Methodendeklaration hinzuzufügen. –

+0

Entschuldigung, wurde bei der Arbeit aufgehängt :) – leppie

6

Check out PredicateBuilder - http://www.albahari.com/nutshell/predicatebuilder.aspx

Dieser Code wird verpacken Ihre where-Klausel als Ausdruck Objekte, die Sie weitergeben können.

Ich habe das Repository-Muster implementiert, und meine Flava ist es, eine Fetch (ICriteria) -Methode zu geben, die die Where-Klausel abhängig von den angegebenen Kriterien aufbaut. Einfach, aber funktioniert für mich.

12

ist die komplette funktionstüchtiges Beispiel, wie LINQ Ausdruck als

using System; 
using System.Linq.Expressions; 
using System.Reflection; 

namespace ConsoleTest 
{ 
    public class Values 
    { 
     public int X { get; set; } 
     public int Y { get; set; } 

     public override string ToString() 
     { 
      return String.Format("[ X={0} Y={1} ]", X, Y); 
     } 
    } 

    class Program 
    { 
     static void Main() 
     { 
      var values = new Values {X = 1, Y = 1}; 

      // pass parameter to be incremented as linq expression 
      IncrementValue(values, v => v.X); 
      IncrementValue(values, v => v.X); 
      IncrementValue(values, v => v.Y); 

      // Output is: [ X=3 Y=2 ] 
      Console.Write(values); 
     } 

     private static void IncrementValue<T>(T obj, Expression<Func<T,int>> property) 
     { 
      var memberExpression = (MemberExpression)property.Body; 
      var propertyInfo = (PropertyInfo)memberExpression.Member; 
      // read value with reflection 
      var value = (int)propertyInfo.GetValue(obj, null); 
      // set value with reflection 
      propertyInfo.SetValue(obj, ++value, null); 
     } 
    } 
} 
+0

Der Link oben in dieser Antwort ist unterbrochen. – Scott

+1

Link entfernt. Codebeispiel wird mit Antwort bereitgestellt –

Verwandte Themen