2009-08-19 12 views
43

Oto scenariusz: mam serię różnych klas repozytoriów, z których każdy może korzystać z izolowanego kontekstu danych lub z udostępnionego kontekstu. W przypadkach, w których używany jest izolowany kontekst, chcę dodać metodę do klasy bazowej, która pozwoli mi określić lambdę jako parametr, aby to wyrażenie było wykonywane przez izolowany kontekst wybranego repozytorium i zwracało wynik IQueryable . Jak wyglądałby podpis metody i jak przekazywać wyrażenie do kontekstu?LINQ: przekazywanie wyrażenia lambda jako parametru do wykonania i zwracanego przez metodę

Potrzebuję, aby rozwiązanie było możliwie jak najbardziej ogólne, ponieważ można użyć dowolnego możliwego obiektu/stołu modelowego.

Tutaj jest po prostu to, czego szukam zrobić:

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

Odpowiedz

57

coś takiego:

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

lub

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

Zastosowanie:

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

lub

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

Założenia:

  1. Tabela może pochodzić z t, jeszcze trzeba będzie zdać źródła zbyt.
  2. W razie potrzeby można zmodyfikować wyrażenie predykatów.
+0

Gdy próbuje swoją pierwszą sugestię, pojawia się błąd w kompilacji Tabela t = pomniane przeżycie (); linia: T musi być typem odniesienia, aby użyć go jako parametru –

+0

nevermind, mam go. konieczne jest dodanie "where T: class" na końcu deklaracji metody. –

+0

Przepraszam, zostałem powiesił się w pracy :) – leppie

6

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

Kod ten będzie pakować swoje where clause jako obiekty ekspresyjne, które można przekazać informacje.

Wdrożyłem wzorzec repozytorium, a moja flava ma przekazać mu metodę pobierania (ICriteria), która tworzy klauzulę Where w zależności od dostarczonych kryteriów. Proste, ale działa dla mnie.

12

Powyżej znajduje się pełna próbka robocza, jak przekazać wyrażenie LINQ jako parametr

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

Link na górze tej odpowiedzi jest uszkodzony. – Scott

+1

Link usunięty. Przykład kodu jest dostarczany z odpowiedzią –

Powiązane problemy