Я пишу программу на C# для преобразования базы данных FoxPro в XML, и все работает, за исключением пустого поля memo. Что-то мне не хватает, чтобы преобразовать этот бит?
Я использую C# .Net 3.5 SP1, драйвер OLE DB для Visual FoxPro 9 SP 1. Строка подключения в порядке, так как все остальные данные извлекаются правильно.
Когда я конвертировал базу данных FoxPro в SQL Server, мемо-поле там также остается пустым, поэтому я не могу выполнить преобразование дважды.





Я не очень хорошо знаком с C#, FoxPro или SQL Server, поэтому не могу дать вам много советов по этому поводу.
Однако, если вы не можете найти подходящий драйвер, вы можете подумать о самостоятельном анализе необработанных данных и файлов заметок. Другой вопрос касался этого:
Какой самый простой способ прочитать DBF-файл FoxPro из Python?
Вы не поверите, но эти форматы файлов довольно просто проанализировать, если вы решите написать свой собственный синтаксический анализатор C#. Эти спецификации доступны в Microsoft:
@Matt: Может быть, тебе стоит опубликовать это в качестве ответа?
Я использую ODBC для связывания таблиц VFP 8, и мемо-поля работают без проблем. Я не знаю, отличается ли OLEDB.
У вас может не быть таблиц Visual FoxPro. Многие системы VFP используют те же таблицы, что и приложение FoxPro 2 или dBase, которое они заменили. Вы можете посмотреть заголовок файла или просто попробовать один из других драйверов ODBC, чтобы проверить, работают ли они.
По-прежнему не повезло. Используя эту строку подключения (конечно, string.Format () 'd): «Драйвер = {{Microsoft Visual FoxPro Driver}}; SourceType = DBF; SourceDB = {0}; Exclusive = No; Collate = Machine; NULL = NO; УДАЛЕНО = НЕТ; ФОН = НЕТ; " Пытался запросить нормально и как осталось (имя_столбца, 8000).
Мне пришлось поработать самому, но, возможно, это поможет кому-то другому в будущем:
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).
Когда я скопировал и вставил этот код, я получил сообщение об ошибке «Невозможно получить доступ к явной реализации IList.Contains». Добавление .ToList() до Contains устранило проблему.
Есть какие-нибудь советы о том, с чего начать работу с документами, чтобы использовать этот индекс для получения данных из мемо-поля?
@reggaeguitar Мой друг, рок-звезда, ты настоящий спаситель! Спасибо
Поговорим о том, как усложнять вещи - есть несколько способов открыть таблицы FoxPro в .NET - Связывание через Access просто ...