nHibernate 生成了这个奇怪的 SQL; SQLS 是不是按原样使用它?
Posted
技术标签:
【中文标题】nHibernate 生成了这个奇怪的 SQL; SQLS 是不是按原样使用它?【英文标题】:nHibernate generated this odd bit of SQL; did SQLS consume it as is?nHibernate 生成了这个奇怪的 SQL; SQLS 是否按原样使用它? 【发布时间】:2018-05-14 08:46:15 【问题描述】:由于以下 LINQ:
plans
.Where(p => p.Attributes.Any(a => a.Attribute.Product.Type == callType) &&
call.StartTime < p.EndDate.GetValueOrDefault(System.Data.SqlTypes.SqlDateTime.MaxValue.Value) &&
call.StartTime > p.StartDate.GetValueOrDefault(System.Data.SqlTypes.SqlDateTime.MinValue.Value))
计划类似于手机计划。假设国际电话的基本价格为每分钟 1 美元,并且该合同的开始和结束时间为空,因为它是基本价格。为 12 月制定了一个特殊计划,从 1 日开始,到该月的最后一天结束。该计划应该覆盖基础(稍后会使用.OrderBy
endtime-starttime [即计划越短,覆盖性越强] + .First
,但这对我来说现在并不感兴趣)但它应该只适用于 12 月拨打的电话,因此这两个条款确保我们只寻找支持电话类型的计划,并且开始/结束日期跨越拨打电话的时间
根据 nHibernate 的输出窗口调试,这将转换为以下 SQL:
and
(exists
(
..blah blah blah..
where product7_.Type=?
)
) and ?<coalesce(plan4_.EndDate, ?) and ?>coalesce(plan4_.StartDate, ?)
我得到 EXISTS (blahblahblah),因为它源自 p.Any()
,但尖括号中的时髦 SQL 是什么?
看起来) and ?<coalesce(plan4_.EndDate, ?) and ?>coalesce(plan4_.StartDate, ?)
应该是(在常规 SQL 语法中)
and call.starttime BETWEEN COALESCE(plan.StartDate, '1753-01-01') AND COALESCE(plan.EndDate, '9999-12-31')
SQLServer 是否使用它作为 nHibernate 的输出,或者 nHibernate 的其他部分负责将其扩展为更像我的“常规”SQL 的东西? (nhibernate运行在sqlserver2008模式,但是目标是azure)
【问题讨论】:
myNullableDate.GetValueOrDefault(someDateValue)
在可空日期,如果 myNullableDate.HasValue
,则返回 myNullableDate.Value
,如果可空日期为空,则返回 someDateValue
值。 COALESCE 返回遇到的第一个非空参数,从左到右读取
我不一定跟踪到达数据库的实际 SQL;我使用拦截器public class SqlStatementInterceptor : EmptyInterceptor public override global::NHibernate.SqlCommand.SqlString OnPrepareStatement(global::NHibernate.SqlCommand.SqlString sql) Trace.WriteLine(sql.ToString()); return sql;
跟踪 nHibernate 准备的 sql
您是否能够运行跟踪并查看提交到数据库的内容?
我不确定;这个项目已经是一个巨大的陌生领域,因为我不在最初的开发团队中,我们的其他东西都没有使用 nH/castlewindsor.. 也许更简单的假设是 nH 在它之后对 SQL 字符串进行了更多的操作完成Prepare
ing 它,因为我几乎 100% 确定 SQLServer 不会对此做任何事情,即使它看起来有点像参数化查询(odbc 风格,记住,而不是 sqlserver @param 风格)。也许闯入拦截器并介入会让我看到它的其他地方
blog.sqlauthority.com/2009/01/07/… 可能会有所帮助
【参考方案1】:
答案是尖括号中没有时髦的 SQL :)
仔细观察,这些是查询中的<
(小于)和>
(大于)运算符,SQL 也支持这些运算符。
缺少空格让您感到困惑。
?
符号是查询中位置参数的常用占位符,因为这些参数不与 SQL 文本内联发送(在本例中,call.StartTime
的值和最大/最小日期值)。
你可以理解为:
and :startTime < coalesce(plan4_.EndDate, :sqlTimeMaxValue) and :startTime > coalesce(plan4_.StartDate, :sqlTimeMinValue)
希望有帮助!
【讨论】:
谢谢弗雷迪;我认为它需要第二双眼睛才能看到这种解释——看不到代码的 sql!以上是关于nHibernate 生成了这个奇怪的 SQL; SQLS 是不是按原样使用它?的主要内容,如果未能解决你的问题,请参考以下文章
NHibernate HQL 生成器支持 SQL Server 2016 时态表
我怎样才能让 NHibernate 只生成 SQL 而不执行它?