2012-01-07 14 views
5

Digamos que tengo una clase como:LINQ propiedad acceso de la variable

public class Foo 
{ 
    public string Title {get;set;} 
} 

Ahora, vamos a suponer que tengo una public List<Foo> myList que quiero filtrar por LINQ como tan:

var x = myList.Where(f => f.Title == myValue); 

Todo es agradable y claro hasta ahora.

Pero, ¿cómo se puede acceder a la propiedad por variable? Algo como:

string myProperty = "Title"; 

var x = myList.Where(f => f.myProperty == myValue); 

Respuesta

12

Se puede escribir un método de extensión

public static class MyExtensions 
{ 
    public static object GetProperty<T>(this T obj, string name) where T : class 
    { 
     Type t = typeof(T); 
     return t.GetProperty(name).GetValue(obj, null); 
    } 
} 

y utilizar de esta manera

var x = myList.Where(f => f.GetProperty("Title") == myValue); 
+0

¡Me encantó! Gracias. – Dementic

3

Este no es el tipo de situación para la que se utiliza LINQ. LINQ es una interfaz fluida para manipular colecciones. Acceder a los miembros a través de una representación textual se realiza con reflexión.

object GetProperty(Foo f, string propertyName) { 
    var type = typeof(Foo); 
    var propInfo = type.GetProperty(propertyName); 
    return propInfo.GetValue(f, null); 
} 
0

que su uso no puede LINQ dynamic query from microsoft aquí es código de ejemplo

var query = db.Customers.Where("City == @0 and Orders.Count >= @1", "London", 10). 
      OrderBy("CompanyName"). 
      Select("New(CompanyName as Name, Phone)"); 
+0

¿Por qué se vinculó a un acuerdo de licencia? –

+1

lol, debe aceptar descargar el código de muestra. – Dementic

1

Si necesita componer sus consultas de forma dinámica sobre la marcha, se puede usar la biblioteca LINQ Dynamic Query, una muestra de Microsoft:

Este ejemplo muestra una técnica para componer declaraciones LINQ en el vuelo , dinámicamente, en tiempo de ejecución.

Referencia a la biblioteca en el código:

using System.Linq.Dynamic; 

Su consulta se vería así:

// You can use a string as the argument for the Where method 
// meaning you can compose this string dynamically 
string myProperty = "Title"; 
var x = myList.Where(myProperty + " = " + myValue); 

También es posible usar marcador de posición en la cadena de consulta, lo que mejora la legibilidad (algo):

var x = myList.Where("@0 = @1", myProperty, myValue); 

Ver a lso este post de Scott Guthrie: Dinámico LINQ Parte 1: Using the LINQ Dynamic Query Library (No creo que alguna vez hubo una parte 2 ...)

Nota: hay que compilar el código de ejemplo de Microsoft y hacer referencia a la ensamblado construido, o podría incluir el código en su propio proyecto.

+0

hmm, cualquier razón por la que no forma parte del .NET Framework estándar, parece tentador ... –

+0

@SurjitSamra En el momento de la primera versión de LINQ (Visual Studio 2008, C# 3.0), Microsoft escribió muchas muestras para ayudar a todos a entender el poder de LINQ. Esta fue solo una de esas muestras, que en sí misma puede ser muy útil, pero puede ser demasiado limitada como para ser parte del marco. –

+0

Si voy a estar en esta situación, entonces francamente preferiré la respuesta de LB –

1

Sé que esto es un hilo viejo, pero aquí es otra manera de hacerlo. Esto tiene la ventaja de ser significativamente más rápido si necesita hacerlo en un bucle. He convertido el resultado de "func" para que sea un objetivo más general.

 var p = Expression.Parameter(typeof(string)); 
     var prop = Expression.Property(p, "Length"); 
     var con = Expression.Convert(prop, typeof(object)); 
     var exp = Expression.Lambda(con, p); 
     var func = (Func<string, object>)exp.Compile(); 

     var obj = "ABC"; 
     int len = (int)func(obj); 

En la pregunta original estaba siendo utilizado el código dentro de LINQ así que la velocidad podría ser bueno.Sería posible usar "func" directo en la cláusula where también si se construyó correctamente, por ejemplo,

 class ABC 
     { 
      public string Name { get; set; } 
     } 

     var p = Expression.Parameter(typeof(ABC)); 
     var prop = Expression.Property(p, "Name"); 
     var body = Expression.Equal(prop, Expression.Constant("Bob")); 
     var exp = Expression.Lambda(body, p); 
     var func = (Func<ABC, bool>)exp.Compile(); 

     ABC[] items = "Fred,Bob,Mary,Jane,Bob".Split(',').Select(s => new ABC() { Name = s }).ToArray(); 
     ABC[] bobs = items.Where(func).ToArray(); 
Cuestiones relacionadas