【问题标题】:Parsing Expression Tree To Sqlstring - Not Reinventing the wheel将表达式树解析为 Sqlstring - 不重新发明轮子
【发布时间】:2011-07-06 06:29:46
【问题描述】:

我需要解析一个表达式树来得到一个 sql where 子句。

.NET FX 或任何第三方库中是否没有任何类已经具备这种能力?

我的意思是Linq2SQL、EntityFramework,它们都必须这样做,所以有没有人知道,是否有可以重复使用的东西而不是重新发明轮子?

MyType.Where(Func<TEntity,bool>((entity)=>entity.Id == 5))) 

现在我需要获取代表 where 子句的相应字符串:

 where abc.Id = "5" 

这只是一个简单的例子。它也应该与逻辑连词一起使用。

我知道我可以创建表达式树并自行解析它,但我认为可能已经存在一些我缺少的东西

【问题讨论】:

  • 不,我有这样的方法 MyType.Where(Func((entity)=>entity.Id == 5))) 现在我需要获取相应的字符串表示where 子句: where abc.Id = "5" 为此,我可以创建一个表达式树并自行解析它。但我觉得,应该有一些已经存在的东西
  • 啊,好吧。也许您可以编辑原始问题并在其中添加额外的信息?

标签: sql string linq parsing expression-trees


【解决方案1】:

您可以创建一个ExpressionVisitor,其唯一目的是查找和处理 where 调用。使这项任务非常容易处理。

例如,

public class WhereCallVisitor : ExpressionVisitor
{
    protected override Expression VisitMethodCall(MethodCallExpression node)
    {
        var method = node.Method;
        if (method.Name == "Where" && method.DeclaringType == typeof(Queryable))
        {   // we are in a Queryable.Where() call
            ProcessWhereCall(node);
        }
        return base.VisitMethodCall(node);
    }

    private void ProcessWhereCall(MethodCallExpression whereCall)
    {
        // extract the predicate expression
        var predicateExpr = ((dynamic)whereCall.Arguments[1]).Operand as LambdaExpression;
        // do stuff with predicateExpr
    }
    // p.s., dynamic used here to simplify the extraction
}

然后使用它:

var query = from row in table
            where row.Foo == "Bar"
            select row.Baz;
var visitor = new WhereCallVisitor();
visitor.Visit(query.Expression);

【讨论】:

  • 我希望我的回答没有偏离基础。正如我理解的问题,给定一个表达式树,你想找到 where 调用并对谓词做一些事情(创建一个表示子句的 SQL 字符串)。仅此一项不会是 the 答案,但它会让你没有太多问题。找到谓词表达式后,应该比较容易得到对应的SQL字符串。
  • 感谢您的回答。这就是我计划实施它的方式。但我认为会有一些开箱即用的东西。但看起来我不需要实现它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 2010-09-19
  • 1970-01-01
  • 2010-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多