How to convert an expression tree to a partial SQL query?

后端 未结 9 1560
轮回少年
轮回少年 2020-11-29 16:26

When EF or LINQ to SQL runs a query, it:

  1. Builds an expression tree from the code,
  2. Converts the expression tree into an SQL query,
  3. Executes th
9条回答
  •  广开言路
    2020-11-29 17:11

    Not sure if this is exactly what you need, but it looks like it might be close:

    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 queryableData = companies.AsQueryable();
    
    // 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>(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>(pe, new ParameterExpression[] { pe }));
    // ***** End OrderBy *****
    
    // Create an executable query from the expression tree.
    IQueryable results = queryableData.Provider.CreateQuery(orderByCallExpression);
    
    // Enumerate the results.
    foreach (string company in results)
        Console.WriteLine(company);
    

提交回复
热议问题