代码之家  ›  专栏  ›  技术社区  ›  sipsorcery

将非常简单的表达式<func<t,bool>>转换为sql where子句

  •  1
  • sipsorcery  · 技术社区  · 15 年前

    我有许多不同的数据源需要查询,并且能够将所有查询限制在非常简单的表达式中,条件不超过2个。我的lamba表达式的典型复杂性的一个例子是:

    b => b.user == "joe" && b.domain == "bloggs.com"
    

    在我的非SQL数据源上,我可以将它们转换为对象列表并使用Linq查询,例如:

    public override T Get(List<T> assets, Expression<Func<T, bool>> whereClause)
    {
        return assets.Where(a => whereClause.Compile()(a)).FirstOrDefault();
    }
    

    我的问题是,当我需要查询一个关系数据库时——我只关心PostgreSQL和MySQL——我有点挣扎。我已经让nhibernate到linq“工作”,但遇到了一些问题,它会暂停和停止访问数据库,或者无法关闭连接,这是在beta版中所期待的,所以我没有抱怨。

    因为我的查询非常简单,我很高兴自己构建SQL,所以我想知道是否有一种相对轻松的方法可以将表达式转换为SQL WHERE子句?

    我快速搜索了一下,找到了一些示例,当然已经有了一些linq-to-sql引擎,所以我知道可以做到。问题是这是否是我一天之内就能想出的办法?这就是我估计需要找到一个兼容的linq-to-sql库,并在运行正常的情况下对其进行负载测试。我确实有很大的性能考虑,所以我更喜欢原始SQL,而不是通过ORM运行。

    2 回复  |  直到 15 年前
        1
  •  0
  •   Andrew Hare    15 年前

    写入LINQ提供程序可以是 非常 很难。我建议查看以下链接:

    Linq Provider for MySql, Postgres, Oracle (这是开源的)
    Writing custom LINQ provider

        2
  •  0
  •   Ralph M. Rickenbach    15 年前

    基于您的注释,您只想从lambda构建一个SQL WHERE子句,让我们来看一下WHERE子句。我将在完整的select语句的上下文中使用它,但是对于update和delete,它是相同的。

    一个例子

    SELECT * FROM b
    WHERE b.user == 'joe' AND b.domain == 'bloggs.com'
    

    如您所见,构建WHERE子句非常容易:

    我认为B是桌子的名字。你只需要:

    • 切断之前的一切 包括“=>”运算符
    • 将所有运算符从lambda更改为SQL语法:“==”变为“=”。
    • 将“&&”更改为“and”,将“”更改为“or”
    • 在字符串操作中相应地更改撇号(“->”。

    您可以使用括号对逻辑进行分组。使用like查找字符串中的子字符串。看一看 this site 用于WHERE子句的语法。

    使用字符串替换来实现魔力:

    str = str.Replace("==", "=");