При реализации 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