NHibernate执行简单查询的时间较长

NHibernate执行简单查询的时间较长,nhibernate,orm,nhibernate-mapping,queryover,nhibernate-criteria,Nhibernate,Orm,Nhibernate Mapping,Queryover,Nhibernate Criteria,我面临着一个非常奇怪的问题,现在它变得令人头痛 NHibernate执行这样一个简单的查询所花费的时间(2-3分钟)比预期的时间(几毫秒)要长。数据库是Oracle,我使用的是ODP驱动程序。我已经检查了所有必要的配置,包括纤维和弹簧,在我看来还可以。当我在sqldeveloper中执行相同的查询时,它以毫秒为单位给出结果 FYI-当我执行另一个查询时,该查询具有三个具有相同NHibernate配置的复杂模型的内部联接,我得到了预期的结果 在调试日志中,我可以看到以下几行代码浪费了时间: 201

我面临着一个非常奇怪的问题,现在它变得令人头痛

NHibernate执行这样一个简单的查询所花费的时间(2-3分钟)比预期的时间(几毫秒)要长。数据库是Oracle,我使用的是ODP驱动程序。我已经检查了所有必要的配置,包括纤维和弹簧,在我看来还可以。当我在sqldeveloper中执行相同的查询时,它以毫秒为单位给出结果

FYI-当我执行另一个查询时,该查询具有三个具有相同NHibernate配置的复杂模型的内部联接,我得到了预期的结果

在调试日志中,我可以看到以下几行代码浪费了时间:

2012-08-17 09:53:20,754 [TestRunnerThread] DEBUG - NHibernate.Connection.DriverConnectionProvider - Obtaining IDbConnection from Driver
2012-08-17 09:55:09,369 [TestRunnerThread] DEBUG - NHibernate.AdoNet.AbstractBatcher - ExecuteReader took 108720 ms
NHibernate属性设置:

<nhibernatePropertiesSettings>
<setting name="nhibernate.connection.provider" serializeAs="String">
 <value>NHibernate.Connection.DriverConnectionProvider</value>
</setting>
<setting name="nhibernate.connection.driver.class" serializeAs="String">
 <value>NHibernate.Driver.OracleDataClientDriver</value>
</setting>
<setting name="nhibernate.dialect" serializeAs="String">
 <value>NHibernate.Dialect.Oracle10gDialect</value>
</setting>
<setting name="nhibernate.show.sql" serializeAs="String">
 <value>true</value>
</setting>
<setting name="nhibernate.query.substitutions" serializeAs="String">
 <value>true 1, false 0, yes 'Y', no 'N'</value>
</setting>
<setting name="nhibernate.use.proxy.validator" serializeAs="String">
 <value>false</value>
</setting>
<setting name="nhibernate.template.flush.mode" serializeAs="String">
 <value>Never</value>
</setting>
</nhibernatePropertiesSettings>

NHibernate.Connection.DriverConnectionProvider
NHibernate.Driver.OracleDataClientDriver
NHibernate.方言
真的
真1,假0,是“Y”,否“N”
假的
从未
弹簧特性设置:

<springPropertiesSettings>
 <setting name="spring.db.provider" serializeAs="String">
  <value>OracleODP-11-2.0</value>
 </setting>
</springPropertiesSettings>

OracleODP-11-2.0
映射:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="XYZ.PaymentInvestigation.Service.Model.PaymentMessageHistory, PaymentInvestigation.Service.Model" table="MESSAGE_HIST_T" lazy="false">    
    <composite-id name="PaymentMessageHistoryId" class="XYZ.PaymentInvestigation.Service.Model.PaymentMessageHistoryId, PaymentInvestigation.Service.Model" unsaved-value="undefined">
      <key-property name="TransactionDate" column="TRN_DATE" />
      <key-property name="TransactionReferenceNumber" column="TRN_NUMBER" />
      <key-property name="TransactionTimeStamp" column="TRN_TIMESTAMP" />
      <key-property name="HistoryNumber" type="AnsiString" column="HIST_NO" />
      <key-property name="SubHistoryNumber" type="AnsiString" column="SUB_HIST_NO" />
    </composite-id>
    <property name="EntryType" column="ENTRY_TYPE" update="false" insert="false" />
    <property name="Location" column="LOC" update="false" insert="false" />
    <property name="QueLineId" column="QUE_LINE_ID" update="false" insert="false" />
    <property name="DateTime" column="DATE_TIME" update="false" insert="false" />
    <property name="SequenceNo" column="SEQUENCE_NO" update="false" insert="false" />
    <property name="OperatorInitials" column="OPR_INITIALS" update="false" insert="false" />
    <property name="Amount" column="AMOUNT" update="false" insert="false" />
    <property name="MsgInfo" column="MSG_INFO" update="false" insert="false" />
    <property name="RecordExpired" column="RECORD_EXPIRED" update="false" insert="false" />
    <property name="RecordUpdated" column="RECORD_UPDATED" update="false" insert="false" />
    <property name="Details" column="DETAILS" update="false" insert="false" /> 
 </class>

查询:

IList<PaymentMessageHistory> paymentMessageHistories =
    HibernateTemplate.ExecuteFind(session => session
        .QueryOver<PaymentMessageHistory>()
        .Where(x =>
            x.PaymentMessageHistoryId.TransactionDate == paymentMessageId.TransactionDate &&
            x.PaymentMessageHistoryId.TransactionReferenceNumber == paymentMessageId.TransactionReferenceNumber)
        .List());
IList paymentMessageHistories=
HibernateTemplate.ExecuteFind(会话=>session
.QueryOver()
.其中(x=>
x、 PaymentMessageHistoryId.TransactionDate==paymentMessageId.TransactionDate&&
x、 PaymentMessageHistoryId.TransactionReferenceNumber==paymentMessageId.TransactionReferenceNumber)
.List());
PaymentMessageHistoryId模型:

public class PaymentMessageHistoryId : IEquatable<PaymentMessageHistoryId>
{
    public virtual DateTime TransactionDate { get; set; }
    public virtual int TransactionReferenceNumber { get; set; }
    public virtual double TransactionTimeStamp { get; set; }
    public virtual string HistoryNumber { get; set; }
    public virtual string SubHistoryNumber { get; set; }

    public bool Equals(PaymentMessageHistoryId other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return other.TransactionDate.Equals(TransactionDate) && other.TransactionReferenceNumber == TransactionReferenceNumber && other.TransactionTimeStamp.Equals(TransactionTimeStamp) && Equals(other.HistoryNumber, HistoryNumber) && Equals(other.SubHistoryNumber, SubHistoryNumber);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != typeof (PaymentMessageHistoryId)) return false;
        return Equals((PaymentMessageHistoryId) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int result = TransactionDate.GetHashCode();
            result = (result*397) ^ TransactionReferenceNumber;
            result = (result*397) ^ TransactionTimeStamp.GetHashCode();
            result = (result*397) ^ (HistoryNumber != null ? HistoryNumber.GetHashCode() : 0);
            result = (result*397) ^ (SubHistoryNumber != null ? SubHistoryNumber.GetHashCode() : 0);
            return result;
        }
    }

    public static bool operator ==(PaymentMessageHistoryId left, PaymentMessageHistoryId right)
    {
        return Equals(left, right);
    }

    public static bool operator !=(PaymentMessageHistoryId left, PaymentMessageHistoryId right)
    {
        return !Equals(left, right);
    }

    public override string ToString()
    {
        return string.Format("TransactionDate: {0}, TransactionReferenceNumber: {1}, TransactionTimeStamp: {2}, HistoryNumber: {3}, SubHistoryNumber: {4}", TransactionDate, TransactionReferenceNumber, TransactionTimeStamp, HistoryNumber, SubHistoryNumber);
    }
公共类PaymentMessageHistoryId:IEquatable
{
公共虚拟日期时间事务日期{get;set;}
公共虚拟int事务引用编号{get;set;}
公共虚拟双事务时间戳{get;set;}
公共虚拟字符串HistoryNumber{get;set;}
公共虚拟字符串SubHistoryNumber{get;set;}
公共布尔等于(PaymentMessageHistoryId其他)
{
if(ReferenceEquals(null,other))返回false;
if(ReferenceEquals(this,other))返回true;
返回other.TransactionDate.Equals(TransactionDate)和&other.TransactionReferenceNumber==TransactionReferenceNumber和&other.TransactionTimeStamp.Equals(TransactionTimeStamp)和&Equals(other.HistoryNumber,HistoryNumber)和&Equals(other.SubHistoryNumber,SubHistoryNumber);
}
公共覆盖布尔等于(对象对象对象)
{
if(ReferenceEquals(null,obj))返回false;
if(ReferenceEquals(this,obj))返回true;
if(obj.GetType()!=typeof(PaymentMessageHistoryId))返回false;
返回等于((PaymentMessageHistoryId)obj);
}
公共覆盖int GetHashCode()
{
未经检查
{
int result=TransactionDate.GetHashCode();
结果=(结果*397)^TransactionReferenceNumber;
结果=(结果*397)^TransactionTimeStamp.GetHashCode();
结果=(结果*397)^(HistoryNumber!=null?HistoryNumber.GetHashCode():0);
结果=(结果*397)^(SubHistoryNumber!=null?SubHistoryNumber.GetHashCode():0);
返回结果;
}
}
公共静态布尔运算符==(PaymentMessageHistoryId左,PaymentMessageHistoryId右)
{
返回等于(左、右);
}
公共静态布尔运算符!=(PaymentMessageHistoryId左,PaymentMessageHistoryId右)
{
返回!等于(左,右);
}
公共重写字符串ToString()
{
返回string.Format(“TransactionDate:{0},TransactionReferenceNumber:{1},TransactionTimeStamp:{2},HistoryNumber:{3},SubHistoryNumber:{4}”,TransactionDate,TransactionReferenceNumber,TransactionTimeStamp,HistoryNumber,SubHistoryNumber);
}
PaymentMessageHistory模型:

public class PaymentMessageHistory : IEquatable<PaymentMessageHistory>
{
    public virtual PaymentMessageHistoryId PaymentMessageHistoryId { get; set; }
    public virtual string EntryType { get; set; }
    public virtual string Location { get; set; }
    public virtual string QueLineId { get; set; }
    public virtual string DateTime { get; set; }
    public virtual string SequenceNo { get; set; }
    public virtual string OperatorInitials { get; set; }
    public virtual decimal Amount { get; set; }
    public virtual string MsgInfo { get; set; }
    public virtual double RecordExpired { get; set; }
    public virtual string RecordUpdated { get; set; }
    public virtual string Details { get; set; }

    public bool Equals(PaymentMessageHistory other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return Equals(other.PaymentMessageHistoryId, PaymentMessageHistoryId) && Equals(other.EntryType, EntryType) && Equals(other.Location, Location) && Equals(other.QueLineId, QueLineId) && Equals(other.DateTime, DateTime) && Equals(other.SequenceNo, SequenceNo) && Equals(other.OperatorInitials, OperatorInitials) && other.Amount == Amount && Equals(other.MsgInfo, MsgInfo) && other.RecordExpired.Equals(RecordExpired) && Equals(other.RecordUpdated, RecordUpdated) && Equals(other.Details, Details);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != typeof (PaymentMessageHistory)) return false;
        return Equals((PaymentMessageHistory) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int result = (PaymentMessageHistoryId != null ? PaymentMessageHistoryId.GetHashCode() : 0);
            result = (result*397) ^ (EntryType != null ? EntryType.GetHashCode() : 0);
            result = (result*397) ^ (Location != null ? Location.GetHashCode() : 0);
            result = (result*397) ^ (QueLineId != null ? QueLineId.GetHashCode() : 0);
            result = (result*397) ^ (DateTime != null ? DateTime.GetHashCode() : 0);
            result = (result*397) ^ (SequenceNo != null ? SequenceNo.GetHashCode() : 0);
            result = (result*397) ^ (OperatorInitials != null ? OperatorInitials.GetHashCode() : 0);
            result = (result*397) ^ Amount.GetHashCode();
            result = (result*397) ^ (MsgInfo != null ? MsgInfo.GetHashCode() : 0);
            result = (result*397) ^ RecordExpired.GetHashCode();
            result = (result*397) ^ (RecordUpdated != null ? RecordUpdated.GetHashCode() : 0);
            result = (result*397) ^ (Details != null ? Details.GetHashCode() : 0);
            return result;
        }
    }

    public static bool operator ==(PaymentMessageHistory left, PaymentMessageHistory right)
    {
        return Equals(left, right);
    }

    public static bool operator !=(PaymentMessageHistory left, PaymentMessageHistory right)
    {
        return !Equals(left, right);
    }

    public override string ToString()
    {
        return string.Format("PaymentMessageHistoryId: {0}, EntryType: {1}, Location: {2}, QueLineId: {3}, DateTime: {4}, SequenceNo: {5}, OperatorInitials: {6}, Amount: {7}, MsgInfo: {8}, RecordExpired: {9}, RecordUpdated: {10}, Details: {11}", PaymentMessageHistoryId, EntryType, Location, QueLineId, DateTime, SequenceNo, OperatorInitials, Amount, MsgInfo, RecordExpired, RecordUpdated, Details);
    }
公共类PaymentMessageHistory:IEquatable
{
公共虚拟PaymentMessageHistoryId PaymentMessageHistoryId{get;set;}
公共虚拟字符串入口类型{get;set;}
公共虚拟字符串位置{get;set;}
公共虚拟字符串QueLineId{get;set;}
公共虚拟字符串日期时间{get;set;}
公共虚拟字符串SequenceNo{get;set;}
公共虚拟字符串运算符初始值{get;set;}
公共虚拟十进制数{get;set;}
公共虚拟字符串MsgInfo{get;set;}
公共虚拟双记录过期{get;set;}
公共虚拟字符串记录更新{get;set;}
公共虚拟字符串详细信息{get;set;}
公共布尔等于(PaymentMessageHistory其他)
{
if(ReferenceEquals(null,other))返回false;
if(ReferenceEquals(this,other))返回true;
返回等于(other.PaymentMessageHistoryId,PaymentMessageHistoryId)和等于(other.EntryType,EntryType)和等于(other.Location,Location)和等于(other.QueLineId,QueLineId)和等于(other.DateTime,DateTime)和等于(other.SequenceNo,SequenceNo)和等于(other.OperatorInitials,OperatorInitials)和other.Amount==金额和等于(other.MsgInfo,MsgInfo)和&other.RecordExpired.Equals(RecordExpired)和&Equals(other.RecordUpdated,RecordUpdated)和&Equals(other.Details,Details);
}
公共覆盖布尔等于(对象对象对象)
{
if(ReferenceEquals(null,obj))返回false;
if(ReferenceEquals(this,obj))返回true;
if(obj.GetType()!=typeof(PaymentMessageHistory))返回false;
返回等于((PaymentMessageHistory)obj);
}
公共覆盖int GetHashCode()
{
未经检查
{
int result=(PaymentMessageHistoryId!=null?PaymentMessageHistoryId.GetHashCode():0);
结果=(结果*397)^(EntryType!=null?EntryType.GetHashCode():0);
结果=(结果*397)^(位置!=null?位置。GetHashCode():0);
结果=(结果*397)^(QueLineId!=null?QueLineId.GetHashCode():0);
结果=(结果*397)^(日期)
public class OracleDataClientDriver2 : OracleDataClientDriver
{
    protected override void InitializeParameter(IDbDataParameter dbParam, string name, SqlType sqlType)
    {
        switch (sqlType.DbType)
        {
            //Timestamp columns not indexed by Oracle 11g date columns. - Use Date 
            case DbType.DateTime:
                base.InitializeParameter(dbParam, name, SqlTypeFactory.Date);
                break;
            default:
                base.InitializeParameter(dbParam, name, sqlType);
                break;
        }
    }
}
<key-property name="TransactionDate" type="Date" column="TRN_DATE" />