2012-01-24 6 views
7

T'un bir nesne olduğu IEnumerable<T> olduğu düşünüldüğünde, çalışma adlarından birinin adını bir dize olarak bildiğim için, belirli bir özelliği nasıl seçebilirim? ÖrneğinÇalışma zamanında IEnumerable <T>'da dinamik bir Select'i nasıl oluşturabilirim?

:

var externalIEnumerable = DataPassedFromConsumingCode(); // `IEnumerable<T>` 

string knownPropertyName = "Foo"; 
var fooSelect = externalIEnumerable.Select(...); 

Özünde, Açıkçası sadece externalIEnumerable.Select(x=> x.Foo); yapıyorum, ama başlangıçta oluşturulduğu zaman üzerinde kontrol sahibi olmadığı zamanlarda ben zamanında bu Select gerçekleştirmek gerekir.

-

YANIT

: Alant cevabı dayanarak, burada ben aslında bunu yaptık: Compile arayarak IQueryable numaralandırılmış edilmesine neden çünkü

public Expression<Func<TItem, object>> SelectExpression<TItem>(string fieldName) 
{ 
    var param = Expression.Parameter(typeof(TItem), "item"); 
    var field = Expression.Property(param, fieldName); 
    return Expression.Lambda<Func<TItem, object>>(field, 
     new ParameterExpression[] { param }); 
} 

Ben, Bir İfadesi Olarak tuttu hangi veritabanı gereksiz yere vurulduğu anlamına geliyordu. Yani, kullanmak, sadece aşağıdakileri yapın:

string primaryKey = _map.GetPrimaryKeys(typeof(TOriginator)).Single(); 
var primaryKeyExpression = SelectExpression<TOriginator>(primaryKey); 
var primaryKeyResults = query.Select(primaryKeyExpression).ToList(); 
+0

IEnumerable'da T'yi kısıtlayabilir misiniz? – Jason

+1

Bu linux'a özgü bir soru değil, değil mi? Bir özelliğe, kod içinde statik olarak değil, adlara dinamik olarak nasıl erişileceğini mi soruyorsunuz? –

+0

Açıklamak gerekirse, sizin T'niz bir şey olabilir, mülkünüz herhangi bir şey olabilir, sadece bir ip olarak mülk ismini alacaksınız? –

cevap

6

Bir İfade

örneğin kullanarak bunu yapmak mümkündür

private class Foo { 
    public string Bar { get; set; } 
} 

private IEnumerable<Foo> SomeFoos = new List<Foo>() { 
    new Foo{Bar = "Jan"}, 
    new Foo{Bar = "Feb"}, 
    new Foo{Bar = "Mar"}, 
    new Foo{Bar = "Apr"}, 
}; 

[TestMethod] 
public void GetDynamicProperty() { 

     var expr = SelectExpression<Foo, string>("Bar"); 
     var propValues = SomeFoos.Select(expr); 

     Assert.IsTrue(new[] { "Jan", "Feb", "Mar", "Apr" }.SequenceEqual(propValues)); 

    } 

public static Func<TItem, TField> SelectExpression<TItem, TField>(string fieldName) { 

    var param = Expression.Parameter(typeof(TItem), "item"); 
    var field = Expression.Property(param, fieldName); 
    return Expression.Lambda<Func<TItem, TField>>(field, new ParameterExpression[] { param }).Compile(); 

} 

hth,
Alan.

0

vaka kullanımınızı sığabilir izin verir.