Создать файл.DBF из записей таблицы SQL
Я хочу создать .DBF
файл из записей таблицы SQL.
Например, если есть таблица с именем CountryMaster
в SQL и имеет 5 столбцов:
- ID int идентичность (1,1)
- Имя варчар (100)
- Детали варчар (200)
- Бит состояния
- CreatedDate datetime
И это имеет 100 строк.
Как я могу экспортировать эти записи с заголовками в .DBF
файл из C#?
ПРИМЕЧАНИЕ: создано .DBF
Размер файла должен быть очень компактным.
4 ответа
Вы можете увидеть структуру файла данных Xbase (*.dbf) и написать свой собственный код, но я реализовал его и использовал его годами. Здесь вы можете найти его на GitHub
Как пользоваться библиотекой
В файле с именем DbfFile.cs есть несколько методов записи. Вы можете использовать любой из них. Я объясню некоторые из них:
Первый метод записи
Сохранить DataTable
как файл dbf:
static void Write(string fileName, System.Data.DataTable table, Encoding encoding)
fileName
: это место, которое вы хотите.dbf
выходной файл будет сохранен.table
: ваши данные, которые вы прочитали с SQL Server или из любого другого источника.encoding
: кодировка, которая будет использоваться при сохранении строковых данных
Второй метод записи
Сохранить List<T>
в файл DBF.
static void Write<T>(string fileName,
List<T> values,
List<Func<T, object>> mapping,
List<DbfFieldDescriptor> columns,
Encoding encoding)
Прочитайте базу данных и сохраните результат в некотором типе класса, затем сохраните значение класса в файл dbf, используя этот метод. Вот описание его параметров:
fileName
: имя файла dbf для сохраненияvalues
: Ваши данные в виде списка объектов типаT
быть сохраненным в файл DBFmapping
Список функций, которые сообщают этому методу, как извлекать данные из типа класса.columns
: информация столбца dbfencoding
: кодировка файла dbf.
Пример для второго метода записи
Поскольку первый подход прост, я предоставлю вам пример второго метода записи. Считайте, что вы хотите сохранить List<MyClass>
данные в файл DBF. Вот код
class MyClass
{
public int Id {get;set;}
public string Name {get;set;}
}
Теперь вы можете сохранить List<MyClass>
в файл DBF, как это:
var idColumn = DbfFieldDescriptors.GetIntegerField("Id");
var nameColumn = DbfFieldDescriptors.GetStringField("Name");
var columns = new List<DbfFieldDescriptor>() { idColumn, nameColumn };
Func<MyClass, object> mapId = myClass => myClass.Id;
Func<MyClass, object> mapName = myClass => myClass.Name;
var mapping = new List<Func<MyClass, object>>() { mapId, mapName };
List<MyClass> values = new List<MyClass>();
values.Add(new MyClass() { Id = 1, Name = "name1" });
DbfFileFormat.Write(@"C:\yourFile.dbf", values, mapping, columns, Encoding.ASCII);
Также с помощью этой библиотеки вы можете читать файлы DBF и ваш код не зависит от
Microsoft.Jet.OLEDB
или что-нибудь еще.
наслаждайся этим.
В основном всю необходимую информацию можно увидеть в разделе " Проблема с вставкой в файл.dbf", поскольку в ней показано, как создать таблицу и вставить в нее значения при создании файла.dbf. Вам нужно будет внести некоторые изменения в поля, которые вы указали, но на странице описано все, что вам нужно.
Чтобы предложить вам решение на C#, я бы начал с загрузки Microsoft Visual Foxpro OleDb Provider, который работает с таблицами.DBF.
в верхней части кода C# добавьте
using System.Data.SqlClient;
using System.Data.OleDb;
Затем в методе для перемещения данных
void MoveFromSQLToDBF()
{
// have a table to pull down your SQL Data...
var dataFromSQL = new DataTable();
// However your connection to your SQL-Server
using (var sqlConn = new SqlConnection("YourSQLConnectionString"))
{
using (var sqlCmd = new SqlCommand("", sqlConn))
{
// Get all records from your table
sqlCmd.CommandText = "select * from CountryMaster";
sqlConn.Open();
var sqlDA = new SqlDataAdapter();
// populate into a temp C# table
sqlDA.Fill(dataFromSQL);
sqlConn.Close();
}
}
// Now, create a connection to VFP
// connect to a PATH where you want the data.
using (var vfpConn = new OleDbConnection(@"Provider=VFPOLEDB.1;Data Source=C:\SomePathOnYourMachine\"))
{
using (var vfpCmd = new OleDbCommand("", vfpConn))
{
// Create table command for VFP
vfpCmd.CommandText = "CREATE TABLE testFromSQL ( ID Numeric(18,0), [Name] Char(100) NULL, [Details] Char(200) NULL, [Status] Logical NULL, [CreateDate] DATETIME NULL)";
vfpConn.Open();
vfpCmd.ExecuteNonQuery();
// Now, change the command to a SQL-Insert command, but PARAMETERIZE IT.
// "?" is a place-holder for the data
vfpCmd.CommandText = "insert into testFromSQL "
+ "( ID, [Name], [Details], [Status], [CreateDate]) values ( ?, ?, ?, ?, ? )";
// Parameters added in order of the INSERT command above..
// SAMPLE values just to establish a basis of the column types
vfpCmd.Parameters.Add( new OleDbParameter( "parmID", 10000000 ));
vfpCmd.Parameters.Add( new OleDbParameter( "parmName", "sample string" ));
vfpCmd.Parameters.Add(new OleDbParameter( "parmDetails", "sample string" ));
vfpCmd.Parameters.Add(new OleDbParameter( "parmStatus", "sample string" ));
vfpCmd.Parameters.Add( new OleDbParameter( "parmCreateDate", DateTime.Now ));
// Now, for each row in the ORIGINAL SQL table, apply the insert to VFP
foreach (DataRow dr in dataFromSQL.Rows)
{
// set the parameters based on whatever current record is
vfpCmd.Parameters[0].Value = dr["ID"];
vfpCmd.Parameters[1].Value = dr["Name"];
vfpCmd.Parameters[2].Value = dr["Details"];
vfpCmd.Parameters[3].Value = dr["Status"];
vfpCmd.Parameters[4].Value = dr["CreateDate"];
// execute it
vfpCmd.ExecuteNonQuery();
}
// Finally, for compactness, use a VFP Script to copy to Excel (CSV) format
using (var vfpCmd2 = new OleDbCommand("", vfpConn))
{
vfpCmd2.CommandType = CommandType.StoredProcedure;
vfpCmd2.CommandText = "ExecScript";
vfpCmd2.Parameters.Add(new OleDbParameter( "csvScript",
@"Use testFromSQL
copy to YourCompactFile.csv type csv
use" ));
vfpCmd2.ExecuteNonQuery();
}
// close VFP connection
vfpConn.Close();
}
}
}
Поскольку OleDb не поддерживает копирование TYPE CSV, я нашел этот пост в S/O, чтобы сделать дамп в формате CSV для вас
Я хотел бы помочь. Тем не менее, id придерживаться простого процесса с OLEDB для VPF.
CREATE TABLE DBF
Это может быть ваш сценарий создания таблицы для.DBF
CREATE TABLE "C:\test.dbf" ([ID] Numeric(18,0), [Name] Char(100) NULL, [Details] Char(200) NULL, [Status] Logical NULL, [CreateDate] DATETIME NULL)
Затем вы можете вызвать его из сценария OLE DB, как показано ниже.
string vpfScript = "CREATE TABLE \"C:\test.dbf\" ([ID] Numeric(18,0), [Name] Char(100) NULL, [Details] Char(200) NULL, [Status] Logical NULL, [CreateDate] DATETIME NULL)";
string connectionString = @"Provider=VFPOLEDB.1;Data Source=C:\test.dbf";
OleDbConnection connection = new OleDbConnection(connectionString);
using (OleDbCommand scriptCommand = connection.CreateCommand())
{
connection.Open();
scriptCommand.CommandType = CommandType.StoredProcedure;
scriptCommand.CommandText = "ExecScript";
scriptCommand.Parameters.Add("myScript", OleDbType.Char).Value = vfpScript;
scriptCommand.ExecuteNonQuery();
}
Строка импорта в таблице
Чтобы импортировать строки в таблицу DBF, это не так, как обычные сценарии SQL, которые мы делаем в других DB.
string vpfScript = "INSERT INTO \"C:\test.dbf\" ([ID], [Name], [Details], [Status], [CreateDate]) VALUES (1,'test john','test details',.t.,{^2015-09-15)";
string connectionString = @"Provider=VFPOLEDB.1;Data Source=C:\test.dbf";
OleDbConnection connection = new OleDbConnection(connectionString);
using (OleDbCommand scriptCommand = connection.CreateCommand())
{
connection.Open();
scriptCommand.CommandType = CommandType.StoredProcedure;
scriptCommand.CommandText = "ExecScript";
scriptCommand.Parameters.Add("myScript", OleDbType.Char).Value = vfpScript;
scriptCommand.ExecuteNonQuery();
}
Вы можете просто изменить значения, которые соответствуют вашим потребностям, как показано ниже.
DataTable dt = new DataTable(); // assuming this is already populated from your SQL Database.
StringBuilder buildInsert = new StringBuilder();
string connectionString = @"Provider=VFPOLEDB.1;Data Source=C:\test.dbf";
OleDbConnection connection = new OleDbConnection(connectionString);
using (OleDbCommand scriptCommand = connection.CreateCommand())
{
connection.Open();
foreach(DataRow dr in dt.Rows)
{
string id = dr["ID"].ToString();
string name = dr["Name"].ToString();
string details = dr["Details"].ToString();
string status = Convert.ToBoolean(dr["Status"]) ? ".t." : ".f.";
string createDate = "{^" + Convert.ToDateTime(dr["CreateDate"]).ToString("yyyy-MM-dd") + "}";
builderInsert.Append("INSERT INTO \"C:\test.dbf\" ([ID], [Name], [Details], [Status], [CreateDate]) VALUES (" + id + ",\"" + name + "\",\"" + details + "\"," + status + "," + createDate + ")" + Environment.NewLine);
scriptCommand.CommandType = CommandType.StoredProcedure;
scriptCommand.CommandText = "ExecScript";
scriptCommand.Parameters.Add("myScript", OleDbType.Char).Value = builderInsert;
scriptCommand.ExecuteNonQuery();
builderInsert = "";
}
}
Пожалуйста, дайте мне знать, если у вас есть другие проблемы. Не забудьте установить это на своей машине. VFP OLE DB