При реализации WEB x64 проекта, в котором предусмотрено получение данных из существующей информационной системы написанной на foxpro 6, использующей dbf файлы столкнулся с тем, что vfpoledb.1 есть только в x32 версии и x64 не существует в природе.
Соответственно для существующего проекта не подходит. Как быть? Отказываться от него не вариант, к возможности использовать SQL запросы при доступе к dbf я уже привык.
Пришлось выносить использование vfpoledb в отдельный x32 сервис Web Api, а из существующего приложения вызывать его методы API.
Исходный код доступен на GitHub
Используются всего три метода:
//Получить строку public async Task<object?> ExecuteCommandScalarAsync(string command) //Получить табличные данные public async Task<ResultQuery> ExecuteCommandReaderAsync(string command) //Выполнить запрос не возвращающий данные public async Task<int> ExecuteCommandNonQueryAsync(string command)
Функции выполнены однотипно, приведу одну из них
public async Task<ResultQuery> ExecuteCommandReaderAsync(string command)
{
using (OleDbConnection? conn2 = new OleDbConnection(_connectionString))
{
using (OleDbCommand? cmd = new OleDbCommand(command, conn2))
{
await conn2.OpenAsync();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "ExecScript";
cmd.Parameters.Add("myScript", OleDbType.Char).Value = @"SET DATE GERMAN";
await cmd.ExecuteNonQueryAsync();
cmd.CommandText = command;
cmd.CommandType = CommandType.Text;
cmd.Parameters.Clear();
ResultQuery results = new ResultQuery();
try
{
using (var reader = await cmd.ExecuteReaderAsync())
{
if (reader.HasRows)
results.DataTable.Load(reader);
await reader.DisposeAsync();
}
}
catch (Exception E)
{
results.Errror = E.Message;
Console.WriteLine("error " + E.Message);
}
await conn2.CloseAsync();
return results;
}
}
}
Предварительный запрос @»SET DATE GERMAN» позволяет выбирать нам даты в привычном германском формате день.месяц.год (01.02.2023).
Пример API вызова:
internal async Task<DataTable> ExecuteCommandReaderAsync(string comm)
{
var param = new Dictionary<string?, string?>() { { "query", comm }, { "basepath", _defaultPath } };
var response = await _httpClient.PostAsync("/api/dbf/GetReaderTable", new FormUrlEncodedContent(param));
var content = await response.Content.ReadAsStringAsync();
return (DataTable)JsonConvert.DeserializeObject(content, (typeof(DataTable)));
}
Для запуска сервиса необходимо:
1. Установить vfpoledb.1
2. В файле appsettings.json прописать пути в разделе Bases