آشنایی با Expression Tree در LINQ
در این بخش به بررسی Expression Tree در زبان کوئری نویسی LINQ پرداخته ایم. همانطور که از اسم آن نیز مشخص است، یک ساختار درختی است که هر گره در آن یک Expression است. برای مثال از Expression Tree می توان برای نمایش یک فرمول ریاضی مانند x < y که در آن x، < و y هر کدام یک گره هستند. یک Expression Tree در حقیقت نمایش in-memory از یک عبارت لامبدا است و فقط عناصر مربوط به کوئری را نگه می دارد نه نتیجه اجرای کوئری را. برای درک بهتر به مثال زیر توجه کنید:
1 | Expression<Func<Student, bool>> isTeenAgerExpr = s => s.age > 12 && s.age < 20; |
کامپایلر Expression فوق را به Expression Tree زیر تبدیل می کند:
1 2 3 4 5 | Expression.Lambda<Func<Student, bool>>( Expression.AndAlso( Expression.GreaterThan(Expression.Property(pe, "Age"), Expression.Constant(12, typeof(int))), Expression.LessThan(Expression.Property(pe, "Age"), Expression.Constant(20, typeof(int)))), new[] { pe }); |
شما خودتان هم می توانید یک Expression Tree ایجاد کنید. برای مثال عبارت لامبدا زیر را در نظر بگیرید:
1 | Func<Student, bool> isAdult = s => s.age >= 18; |
عبارت فوق مشابه متد زیر است:
1 2 3 4 | public bool function(Student s) { return s.Age > 18; } |
برای ساخت Expression Tree ابتدا یک عبارت برای ورودی ایجاد کنید. در این مثال ورودی ما از نوع Student و نام ورودی هم s است. پس عبارت مربوط به ورودی ما به این شکل خواهد بود:
1 | ParameterExpression pe = Expression.Parameter(typeof(Student), "s"); |
حال باید عبارت مربوط به خاصیت Age مربوط به شیء Student را ایجاد کنیم. برای اینکار می توانیم از Expression.Property() استفاده کنیم:
1 | MemberExpression me = Expression.Property(pe, "Age"); |
چون مقدار 18 یک مقدار ثابت است و قرار نیست تغییر کند یک عبارت از نوع Constant برای آن ایجاد می کنیم:
1 | ConstantExpression constant = Expression.Constant(18, typeof(int)); |
تا اینجا ما برای خاصیت Age و مقدار 18 عبارت مورد نیاز را ایجاد کردیم. بعد از آن باید یک عبارت دیگر برای بررسی مقادیر این دو عبارت ایجاد کنیم. برای اینکار می توانیم از متد Expression.GreaterThanOrEqual() استفاده کنیم:
1 | BinaryExpression body = Expression.GreaterThanOrEqual(me, constant); |
حال با استفاده از متد Expression.Lambda می توانیم آن ها را به هم وصل کرده Expression Tree مورد نظر را ایجاد کنیم:
1 | var isAdultExprTree = Expression.Lambda<Func<Student, bool>>(body, new[] { pe }); |
نمونه کامل برای ساخت Expression Tree:
1 2 3 4 5 6 7 8 9 10 | ParameterExpression pe = Expression.Parameter(typeof(Student), "s"); MemberExpression me = Expression.Property(pe, "Age"); ConstantExpression constant = Expression.Constant(18, typeof(int)); BinaryExpression body = Expression.GreaterThanOrEqual(me, constant); var ExpressionTree = Expression.Lambda<Func<Student, bool>>(body, new[] { pe }); Console.WriteLine("Expression Tree: {0}", ExpressionTree); Console.WriteLine("Expression Tree Body: {0}", ExpressionTree.Body); Console.WriteLine("Number of Parameters in Expression Tree: {0}", ExpressionTree.Parameters.Count); Console.WriteLine("Parameters in Expression Tree: {0}", ExpressionTree.Parameters[0]); |
خروجی مثال:
1 2 3 4 | Expression Tree: s => (s.Age >= 18) Expression Tree Body: (s.Age >= 18) Number of Parameters in Expression Tree: 1 Parameters in Expression Tree: s |
هیچ نظری ثبت نشده است