OleDB:DBF 类型映射

发布于 2024-12-08 10:49:47 字数 2237 浏览 1 评论 0原文

我正在尝试读取 dbf 文件。在读取其中的数据之前,我会分析其架构表,以免读取错误的文件。当我分析它时,我检查它的列名称及其类型。我的问题是,在某些系统上,特定字段映射到 System.Double,但在其他系统上,它映射到 System.Int16。事实上,该字段的实际类型(如 DBFNavigator 中所示)是 numeric(4,0)。我编写了一个测试应用程序来检查客户端的 dbf 文件。这是输出 dbf 模式的类:

public class DBFAnalyzerCore:IDisposable
{
    private OleDbConnection _connection;
    private bool _keyInfo;
    private string _fileName;
    bool _bDisposed;

    public DBFAnalyzerCore(string path, bool keyInfo)
    {
        _connection = new OleDbConnection(
            String.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=dBASE IV;User ID=Admin;Password=",
            System.IO.Path.GetDirectoryName(path)));

        _connection.Open();
        _keyInfo = keyInfo;
        _fileName = System.IO.Path.GetFileName(path);
    }

    public void Analyze(StringBuilder result)
    {
        OleDbCommand command = null;
        IDataReader reader = null;

        try
        {
            command = new OleDbCommand(String.Format("SELECT * FROM [{0}]", _fileName), _connection);

            if (_keyInfo)
                reader = command.ExecuteReader(CommandBehavior.KeyInfo);
            else
                reader = command.ExecuteReader();

            DataTable schema = reader.GetSchemaTable();
            OutputShema(schema, result);

        }
        finally
        {
            if (reader != null) reader.Close();

            if (command != null) command.Dispose();
        }
    }

    private void OutputShema(DataTable schema, StringBuilder sb)
    {
        foreach (DataRow row in schema.Rows)
        {
            sb.AppendLine(String.Format("{0} - {1}", row["ColumnName"], row["DataType"]));
        }
    }

    protected virtual void Dispose(bool bDisposing)
    {
        if (bDisposing)
        {
            _connection.Dispose();
            _bDisposed = true;
        }
    }

    public void Dispose()
    {
        Dispose(true);

        GC.SuppressFinalize(this);
    }
}

结果在客户端系统上显示为 System.Int16。系统是Win7 x64。 HKEY_LOCAL_MACHINE\Software\Microsoft\DataAccess\Version 为“6.1.7601.17514”。我的也是这样,但我得到了 System.Double! 同时,在客户的“新”系统上,它显示了 System.Double。什么样的调整/设置可能导致这种情况? 我知道现在我应该删除列类型检查,但由于我们的版本控制政策,我现在无法执行此操作。

I'm trying to read a dbf file. Before I read data in it, I analyze its schema table in order not to read a wrong file. When I analyze it, I check its column names and their types. My problem is that on some systems a particular field maps to System.Double, but on the other it maps to System.Int16. In fact, the actual type of that field (as seen in DBFNavigator) is numeric(4,0). I wrote a test app to check those dbf files on the client`s side. This is the class that outputs the dbf schema:

public class DBFAnalyzerCore:IDisposable
{
    private OleDbConnection _connection;
    private bool _keyInfo;
    private string _fileName;
    bool _bDisposed;

    public DBFAnalyzerCore(string path, bool keyInfo)
    {
        _connection = new OleDbConnection(
            String.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=dBASE IV;User ID=Admin;Password=",
            System.IO.Path.GetDirectoryName(path)));

        _connection.Open();
        _keyInfo = keyInfo;
        _fileName = System.IO.Path.GetFileName(path);
    }

    public void Analyze(StringBuilder result)
    {
        OleDbCommand command = null;
        IDataReader reader = null;

        try
        {
            command = new OleDbCommand(String.Format("SELECT * FROM [{0}]", _fileName), _connection);

            if (_keyInfo)
                reader = command.ExecuteReader(CommandBehavior.KeyInfo);
            else
                reader = command.ExecuteReader();

            DataTable schema = reader.GetSchemaTable();
            OutputShema(schema, result);

        }
        finally
        {
            if (reader != null) reader.Close();

            if (command != null) command.Dispose();
        }
    }

    private void OutputShema(DataTable schema, StringBuilder sb)
    {
        foreach (DataRow row in schema.Rows)
        {
            sb.AppendLine(String.Format("{0} - {1}", row["ColumnName"], row["DataType"]));
        }
    }

    protected virtual void Dispose(bool bDisposing)
    {
        if (bDisposing)
        {
            _connection.Dispose();
            _bDisposed = true;
        }
    }

    public void Dispose()
    {
        Dispose(true);

        GC.SuppressFinalize(this);
    }
}

As a result on the client's system it showed System.Int16. The system is Win7 x64. HKEY_LOCAL_MACHINE\Software\Microsoft\DataAccess\Version is "6.1.7601.17514". The same is mine but I get System.Double!
At the same time on a clients`s "new" system it showed System.Double. What kind of tweaks/settings could have caused this?
I understand that now I should remove column type checking, but due to our versioning policy I can't do that right now.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文