【问题标题】:Turn very simple Expression<Func<T, bool>> into SQL where clause将非常简单的 Expression<Func<T, bool>> 变成 SQL where 子句
【发布时间】:2009-04-14 12:24:35
【问题描述】:

我有许多不同的数据源需要查询,并且能够将所有查询限制为非常简单的表达式,条件不超过 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 “工作”,但是遇到了一些问题,它停止并停止访问数据库或无法关闭连接,这是测试版中典型的事情,所以我没有抱怨。

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

我快速搜索并找到了一些示例,当然已经有一些 Linq-to-SQL 引擎,所以我知道可以做到。问题是我是否可以在一天或更少的努力中完成?这就是我估计我需要找到一个兼容的 Linq-to-SQL 库并对其进行负载测试,假设它工作正常。我确实有很大的性能考虑,所以我更喜欢原始 SQL,而不是通过 ORM 运行。

【问题讨论】:

  • 您想构建一个 LINQ 提供程序还是只是将 lambda 转换为 SQL where 子句?
  • 我只想构建简单的 where 子句。我不想建立一个 LINQ 提供程序,我知道这是一项严肃的工作。

标签: .net sql linq linq-to-sql lambda


【解决方案1】:

编写 LINQ 提供程序可能非常困难。我建议查看这些链接:

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

【讨论】:

  • 我一直在研究 DbLinq,但对于插入另一个库并遇到性能或可靠性问题有点犹豫。尽管如此,它看起来确实比 nHibernate 轻了很多,所以毕竟它可能值得投入一些时间。
  • 哇,DbLinq 看起来真的过时了。
  • 很遗憾,链接已损坏。 :(
【解决方案2】:

基于您只想从 lambda 构建 SQL WHERE 子句的评论,让我们看一下 WHERE 子句。我将在完整的 SELECt 语句的上下文中使用它,但更新和删除是相同的。

一个例子

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

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

我认为 b 是表的名称。然后,您只需:

  • 切断之前的所有内容并 包括“=>”运算符
  • 将所有运算符从 lambda 更改为 SQL 语法:'==' 变为 '='。
  • 将“&&”更改为 AND 和“||”或
  • 在字符串操作中相应地更改撇号 (" -> ')。

您可以使用括号对您的逻辑进行分组。使用 LIKE 在字符串中查找子字符串。查看 this site 以了解 where 子句的语法。

使用字符串替换来变魔术:

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

【讨论】:

  • 那是我想避免的路径,这实际上是我继续前进的地方。在我的情况下,Linq 的好处是我可以执行 b.LastUpdate > DateTime.Now。在日期上执行 ToString 不会有问题,但如果我要开始匹配 DateTime.Now 在字符串中它会变得混乱:(。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多