NHibernate.Exceptions.GenericADOException:无法执行查询

5

我有一个遗留应用程序(vfp 8),需要从中提取数据(不包括插入)。我使用Accnum字段作为主键,在表中定义为字符11。

工厂配置:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<reflection-optimizer use="false" />
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.GenericDialect</property>
<property name="connection.driver_class">NHibernate.Driver.OleDbDriver</property>
<property name="connection.connection_string">Provider=VFPOLEDB.1;Data Source=C:\Analysis\Quantium\development\RD warehouse\_RDAUWH\Data;Collating Sequence=MACHINE</property>
<property name="show_sql">false</property>
</session-factory>
</hibernate-configuration>

这是我的映射文件:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
               assembly="RDLabels"
               namespace="RDLabels.Domain">

  <class name="CustMast">
    <id name="Accnum" column="Accnum" type="string">
    <generator class="assigned"/>
    </id>
    <property name="Fullname" />
    <property name="Add" />
    <property name="State" />
  </class>  
</hibernate-mapping>

这个类:

public class CustMast
{
    private string _accnum;
    public virtual string Accnum
    {
        get { return _accnum; }
        set { _accnum = value; }
    }
    private string _fullname;
    public virtual string Fullname
    {
        get { return _fullname; }
        set { _fullname = value; }
    }
    private string _add;
    public virtual string Add
    {
        get { return _add; }
        set { _add = value; }
    }
    private string _state;
    public virtual string State
    {
        get { return _state; }
        set { _state = value; }
    }
}

这是获取记录的代码:

public CustMast GetByAccnum(String accnum)
{
        using (ISession session = NHibernateHelper.OpenSession())
        {
            CustMast custMast = session
                                .CreateCriteria(typeof(CustMast))
                                .Add(Restrictions.Eq("Accnum", accnum))
                                .UniqueResult<CustMast>();
            return custMast;
        }
}

完整错误如下:
NHibernate.Exceptions.GenericADOException : could not execute query
[ SELECT this_.Accnum as Accnum0_0_, this_.Fullname as Fullname0_0_, this_.Add as Add0_0_, this_.State as State0_0_ FROM CustMast this_ WHERE this_.Accnum = ? ]
Name:cp0 - Value:00059337444
[SQL: SELECT this_.Accnum as Accnum0_0_, this_.Fullname as Fullname0_0_, this_.Add as Add0_0_, this_.State as State0_0_ FROM CustMast this_ WHERE this_.Accnum = ?]
----> System.IndexOutOfRangeException : Invalid index 0 for this OleDbParameterCollection with Count=0. - d:\CSharp\NH\NH\nhibernate\src\NHibernate\Loader\Loader.cs:1590

运行 NHibernate Profiler,它显示:
WARN: 
reflection-optimizer property is ignored out of application configuration file.


WARN: 
System.IndexOutOfRangeException: Invalid index 0 for this OleDbParameterCollection with Count=0.
at System.Data.OleDb.OleDbParameterCollection.RangeCheck(Int32 index)
at System.Data.OleDb.OleDbParameterCollection.GetParameter(Int32 index)
at System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item(Int32 index)
at NHibernate.Driver.DriverBase.ExpandQueryParameters(IDbCommand cmd, SqlString sqlString) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Driver\DriverBase.cs:line 235
at NHibernate.AdoNet.AbstractBatcher.ExpandQueryParameters(IDbCommand cmd, SqlString sqlString) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\AdoNet\AbstractBatcher.cs:line 232
at NHibernate.Loader.Loader.PrepareQueryCommand(QueryParameters queryParameters, Boolean scroll, ISessionImplementor session) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Loader\Loader.cs:line 1152

ERROR: 
Invalid index 0 for this OleDbParameterCollection with Count=0.

你能分享一下SessionFactory的配置吗? - Brijesh Mishra
你能检查一下它是否适用于MsSql2000Dialect方言吗? - Brijesh Mishra
谢谢,我尝试使用MsSql2000Dialect,但结果相同。 - CarbonMan
3个回答

2
我在使用linq查询时遇到了问题,每当我传递参数时就会出现相同的错误。如果我不传递任何参数并执行session.Query(),则可以正常工作。
我为此苦苦挣扎了几天,但我发现了这个Nhibernate jira票据 here。它解释了SQLParameters和Iseries Db2提供程序之间的一个明显问题。
我知道您正在使用不同的提供程序,但您可能会从下载最新的Nhibernate核心源代码、构建它并在项目中引用最新版本中受益。这解决了我的问题。

0
如果您使用ODP.Net,则需要在目标计算机和开发计算机上安装和配置Oracle客户端。
您发布的错误消息可能是由于安装了多个Oracle客户端,或者尝试使用较早版本的客户端与较新版本的odp.net之类的东西造成的。

0

我会尝试的第一件事是在SQL中运行它,看看会发生什么,因为这可能是数据问题。

SELECT this_.Accnum as Accnum0_0_, this_.Fullname as Fullname0_0_, this_.Add as Add0_0_, this_.State as State0_0_ FROM CustMast this_ WHERE this_.Accnum = '00059337444'

您的数据库中的Accnum列是否定义为字符串类型(varchar、nvarchar等)?

编辑 好的,下一步是实际确认发送到FoxPro的SQL。您需要设置日志记录(或下载NHProf的试用版),以查找SQL是否正确。您的设置和代码看起来都正确,但我不确定方言的选择是否会导致问题。

我想你已经看过thisthis了。

编辑2:NHProf错误似乎认为您的Id应该是Int32,因为它看起来正在调用at System.Data.OleDb.OleDbParameterCollection.GetParameter(Int32 index)

我认为您需要将以下内容添加到您的映射中:

<id name="Accnum" column="Accnum" type="string" >

请注意额外的type="string"


正如您建议的那样,我已经测试了SQL并且它可以工作。该数据库是一个传统的Foxpro表格。我在Fox中测试了SQL并且它运行良好。 - CarbonMan
我正在使用VFP 8。我看到了https://dev59.com/RlHTa4cB1Zd3GeqPTamw,这让我决定尝试一下。在配置中不使用proxyfactory.factory_class会引起问题吗?请参见编辑。 - CarbonMan
谢谢你的帮助,Rippo,但是没有运气,字符串类型仍然出现同样的错误信息。 - CarbonMan
@Rippo 看起来驱动程序在参数仍为空时尝试扩展它们。如果省略 id 的类型,则由反射确定。 - Firo
我猜你试过注释掉这个 <reflection-optimizer use="false" /> - Rippo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接