2013-05-08 21 views
6

Voglio creare un metodo come questo:Come implementare il metodo con il parametro espressione 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"); 

Come posso implementare questo metodo?

+0

si desidera creare un metodo che funziona in modo simile al metodo 'Search()', in modo generico? –

+0

@Wim Ombelets sì – Nodir

risposta

9

È possibile attivare un selettore e un valore in un predicato utilizzando 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); 
} 

Poi solo bisogno di fare qualcosa di simile:

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

Se si vuole fare dal banca dati, allora che dipende da ciò che il database è ; per esempio, con LINQ to SQL si potrebbe aggiungere un ulteriore metodo:

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); 
} 

ed impiego:

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

francamente penso che sia più chiaro di utilizzare la versione database.SomeEntities, però.

0

vuoi tipi di dinamica

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

Questa è una parte di ciò che vuole, vuole specificare il tipo di effetti, ma anche decidere di utilizzare un predicato come LinQ può. –

+0

è veramente chiaro a me se/come questo risponde alla domanda ha chiesto –

1

posso solo pensare a questo (con 2 argomenti generici)

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

utilizzo

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

si può sostituire TValue con oggetto per evitare la seconda argomentazione generica, ma vorrei attenervisi.

Btw. Questa grande opera in concomitanza con questo piccolo aiutante

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; 
    } 
} 

Ora è possibile ottenere il nome della proprietà (Id oder Name) in questo esempio chiamando

var name = expression.MemberName(); 
+0

Che cosa succede se il secondo parametro è sempre un bool, che si può forse utilizzarlo come: var result2 = Ricerca (x => x.Name == "Il nome"); –

+0

perché l'OP deve estrarre il nome membro in questo scenario? mi sembra che abbiano solo bisogno di costruire il predicato –

+0

@Marc: non era parte della domanda, ma ho assunto che è ciò che l'OP deve sapere nel metodo di ricerca, ad esempio per costruire una query SQL. –

Problemi correlati