2014-12-11 5 views
11

Utilizzo di C# ...Come creare un LINQ dinamico selezionare la funzione di proiezione da una stringa [] di nomi?

C'è un modo per specificare i nomi di proprietà per una funzione di proiezione su un metodo di selezione LINQ, da una matrice.

public class Album 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public short Rate { get; set; } 
    public string Genre { get; set; } 
    public short Tracks { get; set; } 
} 

public class Class1 
{ 
    private void Some<T>() 
    { 
     // Example of source 
     var names = new[] { "Id", "Name", "Tracks" }; 

     var query = myDataContext. 
        GetTable<T>. 
        AsQueryable(). 
        Select(/* dynamic projection from names array */); 

        // something like 
        // Select(x => new 
        //  { 
        //   x.Id, 
        //   x.Name, 
        //   x.Tracks 
        //  } 

     GoAndDoSomethingWith(query); 
    } 
} 

Questo può essere fatto senza System.Linq.Dynamic?

+0

Qual è il vostro bisogno di fondo qui? Chiaramente se si sta andando a hard-code di un array si potrebbe hardcodificare la query. Cosa stai cercando di ottenere? – Enigmativity

+0

Questo array è solo un esempio, la fonte dei nomi delle raccolte è diversa. – Shin

+0

Sì, ma questo non è il tuo bisogno di fondo. Perché hai bisogno di farlo in questo modo? Cosa stai cercando di ottenere? Qual è la forza trainante? – Enigmativity

risposta

6

È possibile utilizzare i tipi di riflessione e dinamici per generare un oggetto con solo i campi/proprietà specificati.

Di seguito è riportato un modo semplice per farlo. Puoi fare ottimizzazioni, come avere una cache dei tipi per il riflesso. Ma questo dovrebbe funzionare per campi/proprietà semplici.

public static object DynamicProjection(object input, IEnumerable<string> properties) 
{ 
    var type = input.GetType(); 
    dynamic dObject = new ExpandoObject(); 
    var dDict = dObject as IDictionary<string, object>; 

    foreach (var p in properties) 
    { 
     var field = type.GetField(p); 
     if (field != null) 
      dDict [p] = field.GetValue(input); 

     var prop = type.GetProperty(p); 
     if (prop != null && prop.GetIndexParameters().Length == 0) 
      dDict[p] = prop.GetValue(input, null); 
    } 

    return dObject; 
} 

Usage:

//... 
var names = new[] { "Id", "Name", "Tracks" }; 
var projection = collection.Select(x => DynamicProjection(x, names)); 
//... 
Problemi correlati