2010-04-27 28 views
8

İki ödevi içeren (aşağıya gösterildiği gibi) bir lambda ifadesi oluşturmaya çalışıyorum, sonra bir Queryable.Select() yöntemine iletebilirim.Lambda İfade Seçme() sorgusunda kullanılacak

Bir dize değişkeni bir yönteme geçirmeye çalışıyorum ve sonra lambda ifadesini oluşturmak için bu değişkeni kullanıyorum, böylece bir LINQ Seçme sorgusunda kullanabilirim.

Bunun arkasındaki mantığım, birçok sütun adında bir SQL Server veri kaynağına sahip olduğum, kullanıcının seçmesini sağlayacak bir grafik oluşturma uygulaması oluşturuyorum, sütun adını yazarak, istedikleri asıl veri sütununu yazarak grafiğimin y ekseninde görüntülemek için x ekseni daima DateTime'dır. Bu nedenle, onlar esas olarak DateTime değerine göre hangi verileri çizdiklerini seçebilir (bu bir veri ambarı türü uygulamasıdır).

I, örneğin, dolayısıyla alınan verileri depolamak ve bir sınıfı grafik kaynağı olarak kullanmak adres: I (sadece deneysel) kullanılarak nerede madde için bir ekspresyon ağaç oluşturduktan

public class AnalysisChartSource 
{ 
    public DateTime Invoicedate { get; set; } 
    public Decimal yValue { get; set; } 
} 

Dize değeri ve bu iyi çalışır: ancak

public void GetData(String yAxis) 
{ 
    using (DataClasses1DataContext db = new DataClasses1DataContext()) 
    { 
     var data = this.FunctionOne().AsQueryable<AnalysisChartSource>(); 
     //just to get some temp data in.... 

     ParameterExpression pe = Expression.Parameter(typeof(AnalysisChartSource), "p"); 
     Expression left = Expression.MakeMemberAccess(pe, 
               typeof(AnalysisChartSource).GetProperty(yAxis)); 
     Expression right = Expression.Constant((Decimal)16); 
     Expression e2 = Expression.LessThan(left, right); 
     Expression expNew = Expression.New(typeof(AnalysisChartSource)); 

     LambdaExpression le = Expression.Lambda(left, pe); 

     MethodCallExpression whereCall = Expression.Call(
      typeof(Queryable), "Where", new Type[] { data.ElementType }, 
      data.Expression, 
      Expression.Lambda<Func<AnalysisChartSource, bool>>(e2, new ParameterExpression[] { pe })); 
    } 
} 

hem X doldurmak için) ben seçin deyimi için benzer bir yaklaşım denedi ...... ama Select (ihtiyaç olarak sadece çalışmak için bunu elde edemez ve AnalysisChartSource sınıfının Y değerleri şu şekildedir:

.Select(c => new AnalysisChartSource 
{ Invoicedate = c.Invoicedate, yValue = c.yValue}).AsEnumerable(); 
yeryüzünde böyle bir ifade ağaçlarını kurabilir nasıl

... .ya ... noktaya .possibly daha ... Ben tamamen kaçırmış daha kolay bir yol var ..is?

cevap

15

Ifade ağaçlarının nasıl oluşturulacağını öğrenmenin en iyi yolunun, C# derleyicisinin ne yaptığını görmesidir. Yani burada tam bir program:

using System; 
using System.Linq.Expressions; 

public class Foo 
{ 
    public int X { get; set; } 
    public int Y { get; set; } 
} 

class Test 
{ 
    static void Main() 
    { 
     Expression<Func<int, Foo>> builder = 
      z => new Foo { X = z, Y = z }; 
    } 
} 

, o derleme yansıtıcı içinde sonuçlarını açıp .NET 2.0'a optimizasyonu ayarlanır. Sen ana yöntem için bu oluşturulan kodla sonuna kadar:

ParameterExpression expression2; 
Expression<Func<int, Foo>> expression = 
    Expression.Lambda<Func<int, Foo>>(
    Expression.MemberInit(
     Expression.New((ConstructorInfo) methodof(Foo..ctor), new Expression[0]), 
     new MemberBinding[] { Expression.Bind((MethodInfo) methodof(Foo.set_X), 
          expression2 = Expression.Parameter(typeof(int), "z")), 
          Expression.Bind((MethodInfo) methodof(Foo.set_Y), 
              expression2) } 
    ), 
    new ParameterExpression[] { expression2 }); 

Temelde, Expression.MemberInit ne sonra konum olduğunu düşünüyorum.

+0

Jon harika bir fikir. Bu çözüm için sana 100 oy verirdim! :-) – gsharp

+0

Jon, harika! Çok teşekkürler! Gsharp'a katılıyorum, harika bir fikir! - Reflektör benim yeni arkadaşım :-) Tekrar teşekkürler – jameschinnock

+0

@GSharp, Size yardımcı olacağım: +1. – Steven