C# 如何使用C中的OLEDB驱动程序查询带有.NDX索引文件的Foxpro.DBF文件#

C# 如何使用C中的OLEDB驱动程序查询带有.NDX索引文件的Foxpro.DBF文件#,c#,oledb,visual-foxpro,foxpro,oledbconnection,C#,Oledb,Visual Foxpro,Foxpro,Oledbconnection,我有一个Foxpro.DBF文件。我正在使用OLEDB驱动程序读取.DBF文件。我可以查询DBF并利用它的.CDX索引文件(因为它是自动打开的)。我的问题是,我想用.NDX索引文件(打开.DBF时不会自动打开)来查询它。如何使用OLEDB驱动程序在C#中打开.NDX文件,因为DBF非常大,无法搜索没有索引的记录?谢谢大家!下面是我用来读取DBF的代码 OleDbConnection oleDbConnection = null; try {

我有一个Foxpro.DBF文件。我正在使用OLEDB驱动程序读取.DBF文件。我可以查询DBF并利用它的.CDX索引文件(因为它是自动打开的)。我的问题是,我想用.NDX索引文件(打开.DBF时不会自动打开)来查询它。如何使用OLEDB驱动程序在C#中打开.NDX文件,因为DBF非常大,无法搜索没有索引的记录?谢谢大家!下面是我用来读取DBF的代码

OleDbConnection oleDbConnection = null;
        try
        {
            DataTable resultTable = new DataTable();
            using (oleDbConnection = new OleDbConnection("Provider=VFPOLEDB.1;Data Source=P:\\Test\\DSPC-1.DBF;Exclusive=No"))
            {
                oleDbConnection.Open();
                if (oleDbConnection.State == ConnectionState.Open)
                {
                    OleDbDataAdapter dataApdapter = new OleDbDataAdapter();
                    OleDbCommand command = oleDbConnection.CreateCommand();

                    string selectCmd = @"select * from P:\Test\DSPC-1  where dp_file = '860003'";
                    command.CommandType = CommandType.Text;
                    command.CommandText = selectCmd;

                    dataApdapter.SelectCommand = command;
                    dataApdapter.Fill(resultTable);
                    foreach(DataRow row in resultTable.Rows)
                    {
                        //Write the data of each record 
                    }
                }
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        finally
        {
            try
            {
                oleDbConnection.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to close Oledb connection: " + e.Message);
            }
        }

连接字符串应仅引用.dbf文件所在的路径

然后,您的查询只是通过表名进行的

new OleDbConnection("Provider=VFPOLEDB.1;Data Source=P:\\Test\\;Exclusive=No"))

selectCmd = @"select * from DSPC-1  where dp_file = '860003'";
至于使用.NDX,它是如何/在何处创建的。。。这是您使用Visual Foxpro驱动程序的旧数据库文件吗

如果它是一个单独的索引,则可能需要通过ExecScript()显式打开文件,首先使用索引,然后运行查询。这只是一个固定值的示例。您可能必须对其进行参数化,否则您将接受sql注入

cmd.CommandText = string.Format(
@"EXECSCRIPT('
USE DSPC-1 INDEX YourDSPC-1.NDX
SELECT * from DSPC-1 where dp_file = '860003'" );

此外,您可能对表名的连字号有问题,您可能需要将其括在[方括号]中,但如果有问题,则不能为正数。

您的连接字符串应仅引用.dbf文件所在的路径

然后,您的查询只是通过表名进行的

new OleDbConnection("Provider=VFPOLEDB.1;Data Source=P:\\Test\\;Exclusive=No"))

selectCmd = @"select * from DSPC-1  where dp_file = '860003'";
至于使用.NDX,它是如何/在何处创建的。。。这是您使用Visual Foxpro驱动程序的旧数据库文件吗

如果它是一个单独的索引,则可能需要通过ExecScript()显式打开文件,首先使用索引,然后运行查询。这只是一个固定值的示例。您可能必须对其进行参数化,否则您将接受sql注入

cmd.CommandText = string.Format(
@"EXECSCRIPT('
USE DSPC-1 INDEX YourDSPC-1.NDX
SELECT * from DSPC-1 where dp_file = '860003'" );

此外,您可能会对表名的连字号有问题,您可能需要将其用[方括号]括起来,但如果有问题,则不能用正数括起来。

ndx文件在默认情况下不会打开,这些都是过去的事了。真的,您为什么不干脆将索引添加到CDX中呢。如果这不是一个选项,那么您可以使用DRapp提供的ExecScript建议。他非常接近。以下是如何做到这一点:

string myCommand = @"Use ('P:\Test\DSPC-1') alias myData
Set Index To ('P:\Test\DSPC-1_Custom.NDX')
select * from myData ;
  where dp_file = '860003' ;
  into cursor crsResult ;
  nofilter
SetResultset('crsResult')";

DataTable resultTable = new DataTable();
using (oleDbConnection = new OleDbConnection(@"Provider=VFPOLEDB;Data Source=P:\Test"))
{
  oleDbConnection.Open();
  OleDbCommand command = new OleDbCommand("ExecScript", oleDbConnection);
  command.CommandType = CommandType.StoredProcedure;
  command.Parameters.AddWithValue("code", myCommand);

  resultTable.Load(cmd.ExecuteReader());
  oleDbConnection.Close();
}

ndx文件在默认情况下不会被打开,这些都是过去的事情了。真的,为什么不简单地将索引添加到CDX中呢。如果这不是一个选项,那么您可以使用DRapp提供的ExecScript建议。他非常接近。以下是如何做到这一点:

string myCommand = @"Use ('P:\Test\DSPC-1') alias myData
Set Index To ('P:\Test\DSPC-1_Custom.NDX')
select * from myData ;
  where dp_file = '860003' ;
  into cursor crsResult ;
  nofilter
SetResultset('crsResult')";

DataTable resultTable = new DataTable();
using (oleDbConnection = new OleDbConnection(@"Provider=VFPOLEDB;Data Source=P:\Test"))
{
  oleDbConnection.Open();
  OleDbCommand command = new OleDbCommand("ExecScript", oleDbConnection);
  command.CommandType = CommandType.StoredProcedure;
  command.Parameters.AddWithValue("code", myCommand);

  resultTable.Load(cmd.ExecuteReader());
  oleDbConnection.Close();
}


NDX不是VFP创建的文件。我认为这是一个dBase文件。NDX不是VFP创建的文件。我认为它是一个数据库文件。嗨,.NDX是在Foxpro中创建的一个索引文件,它与主DBF文件存储在同一个目录中。如何让SQL利用这个索引文件@DRapp@h2nghia,请参阅提供脚本选项的修订答案。@DRapp,您非常接近。VFP字符串文本的长度限制为255,如果文本中有换行符,ExecScript将无法成功执行。第二,您需要将结果放在光标中,并使用SetResultSet()将结果发送回VFPOLEDB客户端。@CetinBasoz自非.cdx文件可用以来从未真正使用过它们,因此对其持否定态度。另外,感谢您提供的SetResultSet()。我对你的答案投了赞成票。我想,很少有开发人员使用非CDX版本:)我上次使用非CDX索引时可能是foxbase 2.1(这是因为当时不存在CDX)。您好,.NDX是在Foxpro中创建的索引文件,它与主DBF文件存储在同一目录中。如何让SQL利用这个索引文件@DRapp@h2nghia,请参阅提供脚本选项的修订答案。@DRapp,您非常接近。VFP字符串文本的长度限制为255,如果文本中有换行符,ExecScript将无法成功执行。第二,您需要将结果放在光标中,并使用SetResultSet()将结果发送回VFPOLEDB客户端。@CetinBasoz自非.cdx文件可用以来从未真正使用过它们,因此对其持否定态度。另外,感谢您提供的SetResultSet()。我对你的答案投了更高的票。我猜,很少有开发人员使用非CDX版本:)我上次使用非CDX索引时可能是foxbase 2.1(这是因为当时不存在CDX)。谢谢@Cetin Basoz,你的代码运行得非常完美,没有错误,但性能仍然相同。查找记录“860003”大约需要60秒,而我也尝试在我的计算机上使用测试数据,通过索引得到“更快”的结果。也许你的P:驱动器是远程的,它正在浪费时间来引入索引文件?您是否尝试将索引添加到结构性CDX?你有多少行???即使没有任何索引,60s听起来也很慢。顺便说一句,VFP中存在一个已知的优化问题,即表的代码页与OS代码页不同。我的DBF有超过5M条记录。它是15年前创建的,因此.NDX索引文件在系统中的不同位置使用。将其转换为结构化CDX是可能的,但我的老板不喜欢这样:(.你是对的,我的P驱动器是远程的。如果我把它带到本地,查询将需要30秒,但我仍然不能将该性能用于生产。无论如何,我标记了你的答案以供将来参考。谢谢@Cetin Basoz!谢谢@Cetin Basoz,你的代码运行完美,没有错误,但性能仍然相同。大约需要60秒才能查看与记录“860003”相比,我还尝试在我的计算机上使用测试数据,我得到了“更快”带索引的结果。可能您的P:驱动器是远程的,引入索引文件正在浪费时间?您是否尝试将索引添加到结构化CDX?您有多少行???即使没有任何索引,60秒听起来也很慢。顺便说一句,VFP中存在一个已知的优化问题,表的代码页与OS代码页不同。My DBF h超过500万条记录。它是15年前创建的,因此.NDX指数f