كيفية القيام بما يلي: استخدام أشجار التعبير لإنشاء الاستعلامات الديناميكية
في LINQ, تعبير trees are used إلى represent structured queries that الهدف المصادر of بيانات that implement IQueryable<T>. For مثال, the مكون LINQ to SQL موفر implements the IQueryable<T> واجهة for querying relational بيانات stores. C# و Visual Basicترجمة يحول برمجياًrs الاستعلامات التي تستهدف مصادر البيانات هذه في تعليمات برمجية التي تقوم بإنشاء تعبير شجرة في وقت التشغيل. ثم يمكنك تجاوز الموفر الاستعلام تعبير بناء شجرة البيانات وترجمة إلى لغة استعلام مناسب لمصدر البيانات.
تعبير trees are also used في LINQ to represent lambda expressions that are تعيين إلى متغيرات of نوع Expression<TDelegate>.
This موضوع describes how إلى استخدم تعبير trees إلى إنشاء ديناميكي LINQ queries. ديناميكي queries are useful when the specifics of a استعلام are not known at يحول برمجياً الوقت. For مثال, an تطبيق might provide a مستخدم واجهة that enables the إنهاء مستخدم إلى specify واحد أو المزيد predicates إلى عامل تصفية the بيانات. في ترتيب إلى استخدم LINQ for querying, this نوع of تطبيق must استخدم تعبير trees إلى إنشاء the LINQ استعلام at وقت التشغيل.
مثال
يظهر المثال التالي كيفية إلى استخدام أشجار التعبير إلى إنشاء استعلام من IQueryableمصدر البيانات وتنفيذه it. إنشاء تعليمات برمجية شجرة التعبيرات لتمثيل الاستعلام التالي:
C# استعلام
companies.Where(company => (company.ToLower() == "coho winery" || company.Length > 16)).OrderBy(company => company)
Visual أساسى استعلام
companies.Where(Function(company) company.ToLower() = "coho winery" OrElse company.Length > 16).OrderBy(Function(company) company)
The factory وظائف في the System.Linq.Expressions مساحة الاسم are used إلى إنشاء تعبير trees that represent the expressions that make لأعلى the overall استعلام. The expressions that represent calls إلى the قياسي استعلام عامل وظائف refer إلى the Queryable implementations of these وظائف. The final تعبير شجرة هو passed إلى the CreateQuery<TElement>(Expression) implementation of the موفر of the IQueryable بيانات المصدر إلى إنشاء an تنفيذي استعلام of نوع IQueryable. The نتائج are obtained بواسطة enumerating that استعلام متغير.
Dim companies =
{"Consolidated Messenger", "Alpine Ski House", "Southridge Video", "City Power & Light",
"Coho Winery", "Wide World Importers", "Graphic Design Institute", "Adventure Works",
"Humongous Insurance", "Woodgrove Bank", "Margie's Travel", "Northwind Traders",
"Blue Yonder Airlines", "Trey Research", "The Phone Company",
"Wingtip Toys", "Lucerne Publishing", "Fourth Coffee"}
' The IQueryable data to query.
Dim queryableData As IQueryable(Of String) = companies.AsQueryable()
' Compose the expression tree that represents the parameter to the predicate.
Dim pe As ParameterExpression = Expression.Parameter(GetType(String), "company")
' ***** Where(Function(company) company.ToLower() = "coho winery" OrElse company.Length > 16) *****
' Create an expression tree that represents the expression: company.ToLower() = "coho winery".
Dim left As Expression = Expression.Call(pe, GetType(String).GetMethod("ToLower", System.Type.EmptyTypes))
Dim right As Expression = Expression.Constant("coho winery")
Dim e1 As Expression = Expression.Equal(left, right)
' Create an expression tree that represents the expression: company.Length > 16.
left = Expression.Property(pe, GetType(String).GetProperty("Length"))
right = Expression.Constant(16, GetType(Integer))
Dim e2 As Expression = Expression.GreaterThan(left, right)
' Combine the expressions to create an expression tree that represents the
' expression: company.ToLower() = "coho winery" OrElse company.Length > 16).
Dim predicateBody As Expression = Expression.OrElse(e1, e2)
' Create an expression tree that represents the expression:
' queryableData.Where(Function(company) company.ToLower() = "coho winery" OrElse company.Length > 16)
Dim whereCallExpression As MethodCallExpression = Expression.Call(
GetType(Queryable),
"Where",
New Type() {queryableData.ElementType},
queryableData.Expression,
Expression.Lambda(Of Func(Of String, Boolean))(predicateBody, New ParameterExpression() {pe}))
' ***** End Where *****
' ***** OrderBy(Function(company) company) *****
' Create an expression tree that represents the expression:
' whereCallExpression.OrderBy(Function(company) company)
Dim orderByCallExpression As MethodCallExpression = Expression.Call(
GetType(Queryable),
"OrderBy",
New Type() {queryableData.ElementType, queryableData.ElementType},
whereCallExpression,
Expression.Lambda(Of Func(Of String, String))(pe, New ParameterExpression() {pe}))
' ***** End OrderBy *****
' Create an executable query from the expression tree.
Dim results As IQueryable(Of String) = queryableData.Provider.CreateQuery(Of String)(orderByCallExpression)
' Enumerate the results.
For Each company As String In results
Console.WriteLine(company)
Next
' This code produces the following output:
'
' Blue Yonder Airlines
' City Power & Light
' Coho Winery
' Consolidated Messenger
' Graphic Design Institute
' Humongous Insurance
' Lucerne Publishing
' Northwind Traders
' The Phone Company
' Wide World Importers
string[] companies = { "Consolidated Messenger", "Alpine Ski House", "Southridge Video", "City Power & Light",
"Coho Winery", "Wide World Importers", "Graphic Design Institute", "Adventure Works",
"Humongous Insurance", "Woodgrove Bank", "Margie's Travel", "Northwind Traders",
"Blue Yonder Airlines", "Trey Research", "The Phone Company",
"Wingtip Toys", "Lucerne Publishing", "Fourth Coffee" };
// The IQueryable data to query.
IQueryable<String> queryableData = companies.AsQueryable<string>();
// Compose the expression tree that represents the parameter to the predicate.
ParameterExpression pe = Expression.Parameter(typeof(string), "company");
// ***** Where(company => (company.ToLower() == "coho winery" || company.Length > 16)) *****
// Create an expression tree that represents the expression 'company.ToLower() == "coho winery"'.
Expression left = Expression.Call(pe, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
Expression right = Expression.Constant("coho winery");
Expression e1 = Expression.Equal(left, right);
// Create an expression tree that represents the expression 'company.Length > 16'.
left = Expression.Property(pe, typeof(string).GetProperty("Length"));
right = Expression.Constant(16, typeof(int));
Expression e2 = Expression.GreaterThan(left, right);
// Combine the expression trees to create an expression tree that represents the
// expression '(company.ToLower() == "coho winery" || company.Length > 16)'.
Expression predicateBody = Expression.OrElse(e1, e2);
// Create an expression tree that represents the expression
// 'queryableData.Where(company => (company.ToLower() == "coho winery" || company.Length > 16))'
MethodCallExpression whereCallExpression = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { queryableData.ElementType },
queryableData.Expression,
Expression.Lambda<Func<string, bool>>(predicateBody, new ParameterExpression[] { pe }));
// ***** End Where *****
// ***** OrderBy(company => company) *****
// Create an expression tree that represents the expression
// 'whereCallExpression.OrderBy(company => company)'
MethodCallExpression orderByCallExpression = Expression.Call(
typeof(Queryable),
"OrderBy",
new Type[] { queryableData.ElementType, queryableData.ElementType },
whereCallExpression,
Expression.Lambda<Func<string, string>>(pe, new ParameterExpression[] { pe }));
// ***** End OrderBy *****
// Create an executable query from the expression tree.
IQueryable<string> results = queryableData.Provider.CreateQuery<string>(orderByCallExpression);
// Enumerate the results.
foreach (string company in results)
Console.WriteLine(company);
/* This code produces the following output:
Blue Yonder Airlines
City Power & Light
Coho Winery
Consolidated Messenger
Graphic Design Institute
Humongous Insurance
Lucerne Publishing
Northwind Traders
The Phone Company
Wide World Importers
*/
This تعليمات برمجية uses a ثابت رقم of expressions في the predicate that هو passed إلى the Queryable.Where أسلوب. However, you can write an تطبيق that combines a متغير رقم of predicate expressions that depends تشغيل the مستخدم إدخال. You can also vary the قياسي استعلام عوامل تشغيل that are called في the استعلام, depending تشغيل the إدخال من the مستخدم.
التحويل البرمجي للتعليمات البرمجية
إنشاء a جديد تطبيق وحدة تحكم مشروع في Visual Studio.
ثم إضافة مرجع لـ System.Core.dll إن لم يتم الإشارة إليه بالفعل.
قم بتضمين مساحة الاسم النظام.Linq.Expressions.
Copy the code from the example and paste it into the Main method (C#) or the Main Sub procedure (Visual Basic).
راجع أيضًا:
المهام
كيفية القيام بما يلي: تنفيذ شجرة التعبيرات (C# و Visual Basic)
كيفية: تحديد دالة تقييم عوامل التصفية في وقت التشغيل (C# البرمجة دليل) بشكل حيوي