Aracılığıyla paylaş


Nasıl yapılır: deyim ağaçları (C# ve Visual Basic) dinamik sorguları oluşturmak için kullanın

İçinde LINQ, uygulayan veri kaynakları hedefleyen yapılandırılmış sorgu temsil etmek için kullanılan ifade ağaçları IQueryable<T>.Örneğin, LINQ to SQL sağlayıcı uygular IQueryable<T> ilişkisel veri depoları sorgulamak için arabirim.C# ve Visual Basic derleyiciler derleme zamanında bir ifade ağacı yapıları koda hedefleyen bu tür veri kaynakları sorgular.Daha sonra sorgu sağlayıcısı ifade ağaç veri yapısını çapraz geçiş ve veri kaynağı için uygun bir sorgu dile çevirir.

İfade ağaçlarına da kullanılır LINQ türündeki değişkenler için atanmış olan lambda ifadeleri temsil etmek için Expression<TDelegate>.

Bu konuda ifade ağaçları dinamik olarak oluşturmak için nasıl kullanılacağını açıklar LINQ sorgular.Dinamik sorgular, sorgu özellikleri derleme sırasında bilinen olduğunda yararlıdır.Örneğin, bir uygulama, son kullanıcının verilere filtre uygulamak için bir veya daha fazla yüklemler belirtmesine olanak sağlayan bir kullanıcı arabirimi sağlayabilir.Kullanmak için LINQ sorgulamak için bu tür bir uygulama ifade ağaçları oluşturmak için kullanmanız gerekir LINQ zamanında sorgu.

Örnek

Aşağıdaki örnekte, ifade ağaçlarına yönelik bir sorgu oluşturmak için nasıl kullanılacağını gösterir bir IQueryable veri kaynağı ve sonra yürütün.Kod aşağıdaki sorguyu temsil eden bir ifade ağacı yapıları:

C# sorgu

companies.Where(company => (company.ToLower() == "coho winery" || company.Length > 16)).OrderBy(company => company)

Visual Basic sorgu

companies.Where(Function(company) company.ToLower() = "coho winery" OrElse company.Length > 16).OrderBy(Function(company) company)

Fabrika yöntemleri System.Linq.Expressions ad alanı olun Genel Sorgu ifadeleri temsil eden bir ifade ağaçları oluşturmak için kullanılır.Standart sorgu işleci yöntemlerine temsil eden ifadeleri bakın Queryable bu yöntemlerin uygulamaları.Son ifade ağacını geçirilir CreateQuery<TElement>(Expression) sağlayıcının uygulamasına IQueryable veri kaynağı türü yürütülebilir bir sorgu oluşturmak için IQueryable.Sonuçlar, sorgu değişkeni numaralandırılarak elde edilir.

        ' Add an Imports statement for System.Linq.Expressions.

        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

            // Add a using directive for System.Linq.Expressions.

            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
            */

Bu kodu için geçirilen karşılaştırma ifadeler sabit sayıda kullanır Queryable.Where yöntem.Ancak, kullanıcı girişine bağlı bir değişken sayıda doðrulama deyimleri birleştiren bir uygulama yazabilirsiniz.Kullanıcı girişi bağlı olarak sorgu olarak adlandırılan standart sorgu işleçler de değişebilir.

Kod Derleniyor

  • Yeni bir Konsol uygulaması da proje Visual Studio.

  • Zaten başvurulmayan, System.Core.dll bir başvuru ekleyin.

  • System.Linq.Expressions isim uzayı içerir.

  • Kodunu örnekten kopyalayın ve içine yapıştırın Main yöntemi (C#) veya MainSub yordam (Visual Basic).

Ayrıca bkz.

Görevler

Nasıl yapılır: yürütme ifade ağaçları (C# ve Visual Basic)

Nasıl yapılır: yüklemi filtreler (C# Programlama Kılavuzu) çalışma zamanında dinamik olarak belirtin

Kavramlar

İfade ağaçları (C# ve Visual Basic)

Diğer Kaynaklar

LINQ Çiftlik tohum: ifade ağaç Görselleştirici kullanarak