Pregunta

Estoy escribiendo un programa C # para convertir una base de datos FoxPro a XML, y todo funciona, excepto el campo memo está en blanco. ¿Hay algo que me falta para convertir ese bit?

Estoy usando C # .Net 3.5 SP1, Visual FoxPro 9 SP 1 OLE DB Driver. La cadena de conexión está bien, ya que todos los demás datos se extraen correctamente.

Cuando convertí la base de datos FoxPro a SQL Server, el campo memo también está en blanco, por lo que no puedo convertir dos veces.

¿Fue útil?

Solución

Terminé teniendo que hacer algo de trabajo yo mismo, pero tal vez pueda ayudar a alguien más en el futuro:

        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;
    }

Simplemente tome el resultado de eso y úselo como índice en el archivo memo (ese código es bastante simple usando la documentación de MSDN).

Otros consejos

No estoy muy familiarizado con C # o FoxPro o SQL Server, por lo que no puedo darle muchos consejos al respecto.

Sin embargo, si no puede encontrar un controlador adecuado, puede considerar analizar los datos sin procesar y los archivos de notas usted mismo. Otra pregunta se ha ocupado de esto:

¿Cuál es la forma más fácil de leer un archivo FoxPro DBF de Python?

Créalo o no, estos formatos de archivo son bastante fáciles de analizar si decide escribir su propio analizador C #. Estas especificaciones están disponibles en Microsoft:

Utilizo ODBC para vincular tablas VFP 8 y ??los campos memo funcionan sin problemas. No sé si OLEDB es diferente.

Es posible que no tenga tablas de Visual FoxPro aquí. Muchos sistemas VFP usan las mismas tablas que la aplicación FoxPro 2 o dBase que reemplazaron. Puede mirar el encabezado del archivo o simplemente probar uno de los otros controladores ODBC para ver si funcionan.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top