【问题标题】:Mapping Oracle Date to DateTime with Nhibernate 3.2使用 Nhibernate 3.2 将 Oracle 日期映射到日期时间
【发布时间】:2012-04-09 14:19:36
【问题描述】:

首先,一个简单的例子来描述我的问题。

型号

public class User
{
    public virtual String UserID { get; set; }
    public virtual String UserName { get; set; }
    public virtual DateTime LastLoginTime { get; set; }
}

映射

<id name="UserID" type="AnsiString">
  <column name="p_UserID_vc" length="20"></column>
  <generator class="assigned"/>
</id>
<property name="UserName" column="UserName_vc"  type="AnsiString">
<property name="LastLoginTime" column="LastLoginTime_d" type="DateTime">

表格

create table T_User
(
    p_userid_vc         VARCHAR2(20) not null,
    username_vc         VARCHAR2(50),
    lastlogintime_d     DATE,
)

现在,该表中有 100 万用户。我在 LastLoginTime 中创建了一个 oracle 索引。我使用这样的查询:

var list = Responsity<User>.Where(q => q.LastLoginTime <= DateTime.Now &&   
           q.LastLoginTime >= DateTime.Now.AddDays(-7));           

我使用 Nhibernate Profile 来监视真正的 sql 字符串:

select t.p_UserID_vc
  from T_User t
 where t.lastlogintime_d >= TIMESTAMP '2012-03-19 16:58:32.00' /* :p1 */
   and t.lastlogintime_d <= TIMESTAMP '2012-03-26 16:58:32.00' /* :p2 */

它没有使用索引。我认为它应该使用 'to_date' ,以便它可以使用索引。如何配置映射文件?

【问题讨论】:

  • 您的表定义中没有LastLoginTime。它是什么类型的? DATETIMESTAMP?
  • 对不起,我已经编辑过了。 LastLoginTime 的 DBType 是 DATE。我认为 Nhibernate 会使用“to_date”而不是“TIMESTAMP”。但它没有。

标签: oracle nhibernate datetime date


【解决方案1】:

以防万一有人仍在寻找答案,希望这会有所帮助 解决方法是使用正确的方言对其进行配置,在我的情况下是 NHibernate.Dialect.Oracle10gDialect

【讨论】:

    【解决方案2】:

    它可能不使用您的索引有几个原因:

    1. LastLoginTime的数据类型是DATE,但参数是TIMESTAMPs,所以它可能会隐式地将列转换为时间戳,这意味着它不能使用索引。

    2. 基于成本的优化器 (CBO) 可能正在使用表明使用索引的效率低于不使用索引的统计数据。例如,表中的行可能很少,或者直方图可能会告诉 CBO 大量行与您查询的日期范围相匹配。全表扫描优于使用索引的查询的情况并不少见。

    3. 可能表格上的统计数据已经过时,导致 CBO 做出不准确的估计。

    对您的查询执行解释计划以确定原因。

    注意:使用文字值的查询(例如TIMESTAMP '...')的计划很可能与使用绑定变量的查询(例如p1p2)的计划不同。为实际正在执行的查询运行解释计划。

    【讨论】:

    • 您的第一个原因是对的。LastLoginTime 的 DbType 是 DATE。我将 DateTime 发送到 Nhibernate,但它会将参数转换为 TimeStamp。因此数据库无法使用索引。我怎么能修改配置文件直接发送日期时间?
    • 我不知道如何配置 NHibernate,对不起,但你想要的是它使用类似 TO_DATE('2012-03-19 16:58:32','YYYY-MM-DD HH24:MI:SS')...
    • 最后,我通过这个article找到了真正的原因。它是由发送带有DateTime类型参数的参数化查询引起的。oracle会将参数更改为TimeStamp而不是Date。所以我发送Date类型参数。
    猜你喜欢
    • 2023-03-04
    • 2019-08-30
    • 1970-01-01
    • 2014-06-08
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    相关资源
    最近更新 更多