2009-01-09 70 views
2

我正在寫一個C#程序來將FoxPro數據庫轉換爲XML,除了備註字段以外的所有東西都是空白的。有什麼我失蹤轉換那一點?如何使用.NET提取FoxPro備註字段中的數據?

我正在使用C#.Net 3.5 SP1,Visual FoxPro 9 SP 1 OLE DB驅動程序。連接字符串沒問題,因爲所有其他數據都被正確地拉出。

當我將FoxPro數據庫轉換爲SQL Server時,備註字段也是空白的,因此我無法轉換兩次。

回答

3

截至不得不做一些工作,我自己,但也許它可以幫助別人出未來起來:

 public static object GetDbaseOrFoxproRawValue(string DBPath, string TableName, string ColumnName, 
     string CompareColumnName, string CompareValue, bool CompareColumnIsAutoKey) 
    { 
     using (BinaryReader read = new BinaryReader(File.Open(
      Path.Combine(DBPath, TableName + ".dbf"), FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) 
     { 
      // Is it a type of file that I can handle? 
      if (new byte[] { 0x02, 0x03, 0x30, 0x43, 0x63, 0x83, 0x8b, 
          0xcb, 0xf5, 0xfb }.Contains(read.ReadByte())) 
      { 
       // Skip date. 
       read.BaseStream.Seek(3, SeekOrigin.Current); 

       // Read useful datas... 
       uint RecordCount = read.ReadUInt32(); 
       ushort FirstRecord = read.ReadUInt16(); 
       ushort RecordLength = read.ReadUInt16(); 
       int FieldCount = FirstRecord - 296/32; 

       // Make sure things aren't stupid. 
       ColumnName = ColumnName.ToLower(); 
       CompareColumnName = CompareColumnName.ToLower(); 

       // Find target column (field) 
       string temp; 
       UInt32 CompareFieldOffset = uint.MaxValue, FieldOffset = uint.MaxValue; 
       byte CompareFieldLength = 0, FieldLength = 0; 
       char FieldType = ' '; 
       for (int i = 0; i < FieldCount; i++) 
       { 
        read.BaseStream.Seek(32 + (i * 32), SeekOrigin.Begin); 
        temp = Encoding.ASCII.GetString(read.ReadBytes(11)).Replace("\0", "").ToLower(); 
        if (temp == CompareColumnName) 
        { 
         read.ReadChar(); 
         CompareFieldOffset = read.ReadUInt32(); 
         CompareFieldLength = read.ReadByte(); 
        } 
        if (temp == ColumnName) 
        { 
         FieldType = read.ReadChar(); 
         FieldOffset = read.ReadUInt32(); 
         FieldLength = read.ReadByte(); 
        } 

        if (CompareFieldOffset != uint.MaxValue && FieldOffset != uint.MaxValue) 
         break; 
       } 

       // Make sure we can continue. 
       if (CompareFieldOffset == uint.MaxValue || 
        FieldOffset == uint.MaxValue) return null; 

       // Iterate through each record to find the one we want. 
       for (int index = 0; index < RecordCount; index++) 
       { 
        read.BaseStream.Seek(FirstRecord + (index * RecordLength) + CompareFieldOffset, SeekOrigin.Begin); 
        temp = Encoding.Default.GetString(read.ReadBytes(CompareFieldLength)).Replace("\0", ""); 
        if (temp == CompareValue) 
        { 
         read.BaseStream.Seek(FirstRecord + (index * RecordLength) + FieldOffset, SeekOrigin.Begin); 
         switch (FieldType) 
         { 
          case 'M': 
          case 'I': return read.ReadUInt32(); 
          case 'C': 
          default: return Encoding.Default.GetString(read.ReadBytes(FieldLength)).Replace("\0", ""); 
         } 
        } 
       } 
      } 
      else 
      { 
       return null; 
      } 
     } 

     return null; 
    } 

剛剛從搶的結果,並把它作爲一個索引備忘錄文件(即代碼非常簡單,使用MSDN文檔)。

1

我不熟悉C#或FoxPro或SQL Server,所以在這方面我不能給你太多建議。

但是,如果找不到合適的驅動程序,可以考慮自己解析原始數據和備註文件。另一個問題已經處理了這一點:

What's the easiest way to read a FoxPro DBF file from Python?

不管你信不信,這些文件格式是非常簡單的解析,你應該決定編寫自己的C#編譯器。這些規範可從Microsoft:

+0

談論讓事情變得棘手 - 有幾種方法可以在.NET中打開FoxPro表格 - 通過Access進行鏈接很簡單... – Matt 2009-01-09 15:55:59

+0

@Matt:或許您應該將其作爲答案發布? – 2009-01-09 16:40:38

1

我使用ODBC鏈接VFP 8個表和備註字段沒有問題的工作。我不知道OLEDB是不同的。

您可能在這裏沒有Visual FoxPro表。許多VFP系統使用與他們替換的FoxPro 2或dBase應用程序相同的表格。您可以查看文件頭或嘗試使用其他ODBC驅動程序來查看它們是否有效。

+0

仍然沒有運氣。使用這個連接字符串(當然是string.Format()'d):「Driver = {{Microsoft Visual FoxPro Driver}}; SourceType = DBF; SourceDB = {0}; Exclusive = No; Collat​​e = Machine; NULL = NO; DELETED = NO; BACKGROUNDFETCH = NO;」 試圖正常查詢並作爲左側(column_name,8000)。 – 2009-01-09 16:27:31

相關問題