2013-05-08 15 views
6

Chcę utworzyć metodę tak:Jak wdrożyć metodę z parametrem ekspresja C#

var result = database.Search<EntityType>(x=>x.Name, "Entity Name field value"); 
result = database.Search<EntityType>(x=>x.Id, "Entity Id field value"); 
result = database.Search<EntityType2>(x=>x.Id, "Entity2 Id field value"); 
result = database.Search<EntityTypeAny>(x=>x.FieldAny, "EntityAny FieldAny value"); 

Jak mogę wdrożyć tę metodę?

+0

chcesz utworzyć metodę, która działa podobnie do metody 'Search()' w sposób ogólny? –

+0

@Wim Ombelets yes – Nodir

Odpowiedz

9

Można włączyć selektora i wartość w predykatem użyciu Expression.Equal:

static IQueryable<TSource> Search<TSource, TValue>(
    this IQueryable<TSource> source, 
    Expression<Func<TSource,TValue>> selector, 
    TValue value) 
{ 
    var predicate = Expression.Lambda<Func<TSource,bool>>(
     Expression.Equal(
      selector.Body, 
      Expression.Constant(value, typeof(TValue)) 
     ), selector.Parameters); 
    return source.Where(predicate); 
} 

Wtedy po prostu trzeba zrobić coś takiego:

var result = database.SomeEntities.Search(x => x.SomeProp, "value"); 

Jeśli chcesz to zrobić z bazy danych , zależy to od bazy danych :; na przykład, z LINQ-SQL można dodać dodatkową metodę:

static IQueryable<TSource> Search<TSource, TValue>(
    this System.Data.Linq.DataContext database, 
    Expression<Func<TSource, TValue>> selector, 
    TValue value) where TSource : class 
{ 
    IQueryable<TSource> source = database.GetTable<TSource>(); 
    return Search(source, selector, value); 
} 

i zastosowanie:

var result = database.Search<SomeEntity, string>(x => x.SomeProp, "value"); 

szczerze myślę, że jest jaśniejsza użyć wersji database.SomeEntities, choć.

0

chcesz rodzaje dynamicznych

public ReturnType Read<ReturnType>(string FieldName, object dfVal) 
{ 
    if (Res.IsDBNull(Res.GetOrdinal(FieldName))) 
     return dfVal; 
    try { 
     return (ReturnType)Res.GetValue(Res.GetOrdinal(FieldName)); 
    } catch (Exception ex) { 
     return dfVal; 
    } 
} 
+0

Jest to część tego, czego chce, chce określić typ, ale także chce użyć predykatu takiego jak LinQ. –

+0

jest dla mnie naprawdę niejasna, jeśli/jak to odpowiada na zadane pytanie –

1

mogę myśleć tylko o tym (z 2 ogólnych argumentów)

public static IEnumerable<TModel> Search<TModel, TValue>(
     Expression<Func<TModel, TValue>> expression, 
     TValue value 
    ) 
    { 
     return new List<TModel>(); 
    } 

użytkowania

var result = Search<EntityType, int>(x => x.Id, 1); 
var result2 = Search<EntityType, string>(x => x.Name, "The name"); 

można zastąpić TValue z obiektu aby uniknąć drugiego ogólnego argumentu, ale trzymałbym się tego.

Przy okazji. to działa świetnie w połączeniu z tego małego pomocnika

public static class ExpressionHelpers 
{ 
    public static string MemberName<T, V>(this Expression<Func<T, V>> expression) 
    { 
     var memberExpression = expression.Body as MemberExpression; 
     if (memberExpression == null) 
      throw new InvalidOperationException("Expression must be a member expression"); 

     return memberExpression.Member.Name; 
    } 
} 

Teraz można uzyskać nazwę właściwości (ID oder nazwa) w tym przykładzie poprzez wywołanie

var name = expression.MemberName(); 
+0

Co jeśli drugi parametr jest zawsze boolem, niż możesz używać go tak: var result2 = Wyszukaj (x => x.Name == "The Nazwa"); –

+0

dlaczego OP musiałby wyodrębnić nazwę członka w tym scenariuszu? wydaje mi się, że wystarczy skonstruować predykat –

+0

@Marc: to nie było częścią pytania, ale założyłem, że to, co OP musi znać w metodzie wyszukiwania, na przykład do zbudowania zapytania SQL. –

Powiązane problemy