How Read DBF File And Save Data Into Database In C#

In this article, we will learn how to read a DBF file and save all data to the SQL Server database.

Here, in this blog, we will read the DBF file using OleDbConnection and will store the data in two tables.
 
In the first table, we store the columns name and data type containing the DBF file and in the second table, we  store the added data.
 
Use the below namespace.
  1. using System;  
  2. using System.IO;  
  3. using System.Data;  
  4. using System.Data.OleDb;  
  5. using System.Collections.Generic;  
Declare the given variables.
  1. DataTable dtData, dtColumn;  
  2. string rfileName = @"E:\AMIT\DBF_Files\test.dbf";  
  3. string conString = "Data Source=.; Initial Catalog=myDataBase; Integrated Security=SSPI";  
  4. public IList<DbfFieldDescriptor> FieldDescriptors { getset; }  
On page load, we have to read the columns and data contained in the DBF file using OleDbConnection.
  1. private void Form1_Load(object sender, EventArgs e)  
  2. {  
  3.     string filePath = Path.GetDirectoryName(rfileName);  
  4.     OleDbConnection connection = new OleDbConnection("Provider=VFPOLEDB.1;Data Source=" + filePath + ";");  
  5.     connection.Open();  
  6.     DataTable tables = connection.GetSchema(OleDbMetaDataCollectionNames.Tables);  
  7.     dtColumn = null;  
  8.     string fName = Path.GetFileNameWithoutExtension(rfileName);  
  9.     foreach (DataRow rowTables in tables.Rows)  
  10.     {  
  11.         if (rowTables["table_name"].ToString().ToUpper() == fName.ToUpper())  
  12.         {  
  13.             DataTable columns = connection.GetSchema(OleDbMetaDataCollectionNames.Columns,  
  14.                 new String[] { nullnull, rowTables["table_name"].ToString(), null });  
  15.   
  16.             dtColumn = GetColumnDataTable();  
  17.             foreach (System.Data.DataRow rowColumns in columns.Rows)  
  18.             {  
  19.                 DataRow dr = dtColumn.NewRow();  
  20.                 dr[0] = rowColumns["column_name"].ToString();  
  21.                 dr[1] = OleDbType(int.Parse(rowColumns["data_type"].ToString()));  
  22.                 dr[2] = rowColumns["data_type"].ToString();  
  23.                 dr[3] = rowColumns["numeric_precision"].ToString();  
  24.                 dtColumn.Rows.Add(dr);  
  25.             }  
  26.             break;  
  27.         }  
  28.     }  
  29.   
  30.     string sql = "SELECT * FROM " + fName;  
  31.     OleDbCommand cmd = new OleDbCommand(sql, connection);  
  32.     OleDbDataAdapter DA = new OleDbDataAdapter(cmd);  
  33.     dtData = new DataTable();  
  34.     DA.Fill(dtData);  
  35.     connection.Close();  
  36.     WriteDataToDatabase(dtData, dtColumn);  
  37. }  
  38.   
  39. // In this method we have create the table that will be stored the columns name and datatype.  
  40. static DataTable GetColumnDataTable()  
  41. {  
  42.     DataTable table = new DataTable();  
  43.     table.Columns.Add("NAME"typeof(string));  
  44.     table.Columns.Add("TYPE"typeof(string));  
  45.     table.Columns.Add("TYPENO"typeof(string));  
  46.     table.Columns.Add("DEC"typeof(string));  
  47.     return table;  
  48. }  
  49.   
  50. // This method return the datatype name.  
  51. public string OleDbType(int type)  
  52. {  
  53.     string dataType;  
  54.     switch (type)  
  55.     {  
  56.         case 10:  
  57.             dataType = "BigInt";  
  58.             break;  
  59.         case 128:  
  60.             dataType = "Byte";  
  61.             break;  
  62.         case 11:  
  63.             dataType = "Boolean";  
  64.             break;  
  65.         case 8:  
  66.             dataType = "String";  
  67.             break;  
  68.         case 129:  
  69.             dataType = "String";  
  70.             break;  
  71.         case 6:  
  72.             dataType = "Currency";  
  73.             break;  
  74.         case 7:  
  75.             dataType = "DateTime";  
  76.             break;  
  77.         case 133:  
  78.             dataType = "DateTime";  
  79.             break;  
  80.         case 134:  
  81.             dataType = "TimeSpan";  
  82.             break;  
  83.         case 135:  
  84.             dataType = "DateTime";  
  85.             break;  
  86.         case 14:  
  87.             dataType = "Decimal";  
  88.             break;  
  89.         case 5:  
  90.             dataType = "Double";  
  91.             break;  
  92.         case 3:  
  93.             dataType = "Integer";  
  94.             break;  
  95.         case 201:  
  96.             dataType = "String";  
  97.             break;  
  98.         case 203:  
  99.             dataType = "String";  
  100.             break;  
  101.         case 204:  
  102.             dataType = "Byte";  
  103.             break;  
  104.         case 200:  
  105.             dataType = "String";  
  106.             break;  
  107.         case 139:  
  108.             dataType = "Decimal";  
  109.             break;  
  110.         case 202:  
  111.             dataType = "String";  
  112.             break;  
  113.         case 130:  
  114.             dataType = "String";  
  115.             break;  
  116.         case 131:  
  117.             dataType = "Decimal";  
  118.             break;  
  119.         case 64:  
  120.             dataType = "DateTime";  
  121.             break;  
  122.   
  123.         default:  
  124.             dataType = "";  
  125.             break;  
  126.     }  
  127.   
  128.     return dataType;  
  129. }  
After reading the DBF file, here, we need to create the table and save the data.
  1. public void WriteDataToDatabase(DataTable dtData, DataTable dtCol)  
  2. {  
  3.     string TableName = Path.GetFileNameWithoutExtension(rfileName);  
  4.     string FilePath = rfileName;  
  5.     SqlConnection dbCon = new SqlConnection(conString);  
  6.     if (dbCon.State == ConnectionState.Closed)  
  7.         dbCon.Open();  
  8.     string strQuery = "IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'" + TableName + "')) BEGIN SELECT 1 END ELSE BEGIN SELECT 0 END";  
  9.     SqlCommand dbCmd = new SqlCommand(strQuery, dbCon);  
  10.     SqlDataAdapter dbDa = new SqlDataAdapter(dbCmd);  
  11.     DataTable dtExist = new DataTable();  
  12.     dbDa.Fill(dtExist);  
  13.     int valReturn = int.Parse(dtExist.Rows[0][0].ToString());  
  14.     if (valReturn == 0)  
  15.     {  
  16.         ReadFileStream(FilePath, dtCol);  
  17.         CreateDbTable(TableName);  
  18.     }  
  19.   
  20.     saveToDb(dtData, TableName, dtCol);  
  21. }  
  22.   
  23. // this method will create table in the database.  
  24. void CreateDbTable(string TableName)  
  25. {  
  26.     try  
  27.     {  
  28.         SqlConnection dbCon = new SqlConnection(conString);  
  29.         if (dbCon.State == ConnectionState.Closed)  
  30.             dbCon.Open();  
  31.         using (SqlCommand cmd = dbCon.CreateCommand())  
  32.         {  
  33.             StringBuilder sb = new StringBuilder();  
  34.             sb.AppendLine($"CREATE TABLE [{TableName}] (");  
  35.             bool first = true;  
  36.             foreach (var fieldDescriptor in FieldDescriptors)  
  37.             {  
  38.                 if (first)  
  39.                     first = false;  
  40.                 else  
  41.                     sb.Append(", ");  
  42.                 sb.AppendLine($"[{fieldDescriptor.Name}] {fieldDescriptor.GetSqlDataType()}");  
  43.             }  
  44.             sb.Append(", ");  
  45.             sb.AppendLine($"[{"lactivestatus"}] {"bit"}");  
  46.             sb.AppendLine($")");  
  47.             cmd.CommandText = sb.ToString();  
  48.             cmd.ExecuteNonQuery();  
  49.         }  
  50.     }  
  51.     catch (Exception e)  
  52.     {  
  53.         throw new Exception($"Failed to create table {TableName}", e);  
  54.     }  
  55. }  
  56.   
  57. // Here we save records to the database.  
  58. public void saveToDb(DataTable dtOne, string TableName, DataTable dtColumn)  
  59. {  
  60.     if (dtOne.Rows.Count > 0)  
  61.     {  
  62.         SqlConnection dbCon = new SqlConnection(conString);  
  63.         for (int n = 0; n < dtOne.Rows.Count; n++)  
  64.         {  
  65.             if (dbCon.State == ConnectionState.Closed)  
  66.                 dbCon.Open();  
  67.                       
  68.             string strQry = "";  
  69.             strQry = "INSERT INTO [" + TableName + "] VALUES(";  
  70.             for (int i = 0; i < dtColumn.Rows.Count; i++)  
  71.             {  
  72.                 if (i == dtColumn.Rows.Count - 1)  
  73.                 {  
  74.                     if (dtColumn.Rows[i]["TYPE"].ToString().ToLower() == "boolean" || dtColumn.Rows[i]["TYPE"].ToString().ToLower() == "logical")  
  75.                     {  
  76.                         if (string.IsNullOrWhiteSpace(dtOne.Rows[n][i].ToString()))  
  77.                             strQry = strQry + "'False','true')";  
  78.                         else  
  79.                             strQry = strQry + "'" + dtOne.Rows[n][i].ToString() + "','true')";  
  80.                     }  
  81.                     else if (dtColumn.Rows[i]["TYPE"].ToString().ToLower() == "string")  
  82.                     {  
  83.                         if (string.IsNullOrWhiteSpace(dtOne.Rows[n][i].ToString()))  
  84.                             strQry = strQry + "'','true')";  
  85.                         else  
  86.                             strQry = strQry + "'" + dtOne.Rows[n][i].ToString().Replace("'""") + "','true')";  
  87.                     }  
  88.                     else if (dtColumn.Rows[i]["TYPE"].ToString().ToLower() == "byte")  
  89.                     {  
  90.                         if (string.IsNullOrWhiteSpace(dtOne.Rows[n][i].ToString()))  
  91.                             strQry = strQry + "'0','true')";  
  92.                         else  
  93.                             strQry = strQry + "'" + Encoding.ASCII.GetBytes(dtOne.Rows[n][i].ToString()) + "','true')";  
  94.                     }  
  95.                     else if (dtColumn.Rows[i]["TYPE"].ToString().ToLower() == "character")  
  96.                     {  
  97.                         if (string.IsNullOrWhiteSpace(dtOne.Rows[n][i].ToString()))  
  98.                             strQry = strQry + "'','true')";  
  99.                         else  
  100.                             strQry = strQry + "'" + dtOne.Rows[n][i].ToString().Replace("'""") + "','true')";  
  101.                     }  
  102.                     else if (dtColumn.Rows[i]["TYPE"].ToString().ToLower() == "datetime" || dtColumn.Rows[i]["TYPE"].ToString().ToLower() == "date")  
  103.                     {  
  104.                         if (string.IsNullOrWhiteSpace(dtOne.Rows[n][i].ToString()))  
  105.                             strQry = strQry + "null,'true')";  
  106.                         else  
  107.                             strQry = strQry + "'" + DateTime.Parse(dtOne.Rows[n][i].ToString()) + "','true')";  
  108.                     }  
  109.                     else  
  110.                     {  
  111.                         if (string.IsNullOrWhiteSpace(dtOne.Rows[n][i].ToString()))  
  112.                             strQry = strQry + "0,'true')";  
  113.                         else  
  114.                             strQry = strQry + dtOne.Rows[n][i].ToString() + ",'true')";  
  115.                     }  
  116.                 }  
  117.                 else  
  118.                 {  
  119.                     if (dtColumn.Rows[i]["TYPE"].ToString().ToLower() == "boolean" || dtColumn.Rows[i]["TYPE"].ToString().ToLower() == "logical")  
  120.                     {  
  121.                         if (string.IsNullOrWhiteSpace(dtOne.Rows[n][i].ToString()))  
  122.                             strQry = strQry + "'False',";  
  123.                         else  
  124.                             strQry = strQry + "'" + dtOne.Rows[n][i].ToString() + "',";  
  125.                     }  
  126.                     else if (dtColumn.Rows[i]["TYPE"].ToString().ToLower() == "string")  
  127.                     {  
  128.                         if (string.IsNullOrWhiteSpace(dtOne.Rows[n][i].ToString()))  
  129.                             strQry = strQry + "'',";  
  130.                         else  
  131.                             strQry = strQry + "'" + dtOne.Rows[n][i].ToString().Replace("'""") + "',";  
  132.                     }  
  133.                     else if (dtColumn.Rows[i]["TYPE"].ToString().ToLower() == "byte")  
  134.                     {  
  135.                         if (string.IsNullOrWhiteSpace(dtOne.Rows[n][i].ToString()))  
  136.                             strQry = strQry + "'0',";  
  137.                         else  
  138.                             strQry = strQry + "'" + Encoding.ASCII.GetBytes(dtOne.Rows[n][i].ToString()) + "',";  
  139.                     }  
  140.                     else if (dtColumn.Rows[i]["TYPE"].ToString().ToLower() == "character")  
  141.                     {  
  142.                         if (string.IsNullOrWhiteSpace(dtOne.Rows[n][i].ToString()))  
  143.                             strQry = strQry + "'',";  
  144.                         else  
  145.                             strQry = strQry + "'" + dtOne.Rows[n][i].ToString().Replace("'""") + "',";  
  146.                     }  
  147.                     else if (dtColumn.Rows[i]["TYPE"].ToString().ToLower() == "datetime" || dtColumn.Rows[i]["TYPE"].ToString().ToLower() == "date")  
  148.                     {  
  149.                         if (string.IsNullOrWhiteSpace(dtOne.Rows[n][i].ToString()))  
  150.                             strQry = strQry + "null,";  
  151.                         else  
  152.                             strQry = strQry + "'" + DateTime.Parse(dtOne.Rows[n][i].ToString()) + "',";  
  153.                     }  
  154.                     else  
  155.                     {  
  156.                         if (string.IsNullOrWhiteSpace(dtOne.Rows[n][i].ToString()))  
  157.                             strQry = strQry + "0,";  
  158.                         else  
  159.                             strQry = strQry + dtOne.Rows[n][i].ToString() + ",";  
  160.                     }  
  161.                 }  
  162.             }  
  163.                       
  164.             try  
  165.             {  
  166.                 SqlCommand dbCmd1 = new SqlCommand(strQry, dbCon);  
  167.                 dbCmd1.ExecuteNonQuery();  
  168.             }  
  169.             catch (Exception ex)  
  170.             {  
  171.                 Console.WriteLine("Error " + ex.Message);  
  172.             }  
  173.         }  
  174.         dbCon.Close();  
  175.     }  
  176. }  
  177.   
  178. void ReadFileStream(string FilePath, DataTable dtCol)  
  179. {  
  180.     FileStream fileStream = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);  
  181.     BinaryReader binaryReader = new BinaryReader(fileStream);  
  182.   
  183.     var fieldDescriptors = new List<DbfFieldDescriptor>();  
  184.     try  
  185.     {  
  186.         int no = 0;  
  187.         while (true)  
  188.         {  
  189.             var fieldDescriptor = ReadFieldDescriptor(binaryReader, no++, dtCol);  
  190.             if (fieldDescriptor == null)  
  191.                 break;  
  192.             if (no > 1)  
  193.                 fieldDescriptors.Add(fieldDescriptor);  
  194.         }  
  195.     }  
  196.     catch (Exception e)  
  197.     {  
  198.         throw new Exception("Failed to read field descriptors", e);  
  199.     }  
  200.     FieldDescriptors = fieldDescriptors;  
  201. }  
  202.   
  203. DbfFieldDescriptor ReadFieldDescriptor(BinaryReader br, int fdNo, DataTable dtCol)  
  204. {  
  205.     var fieldDescriptor = new DbfFieldDescriptor();  
  206.     fieldDescriptor.No = fdNo;  
  207.     string name = "";  
  208.     if (fdNo > 0 && fdNo <= dtCol.Rows.Count)  
  209.         name = dtCol.Rows[fdNo - 1][0].ToString();  
  210.     try  
  211.     {  
  212.         var fieldNameBytes = new byte[11];  
  213.         fieldNameBytes[0] = br.ReadByte();  
  214.         if (fieldNameBytes[0] == 0x0D)  
  215.             return null// 0x0D means end of field descriptor list  
  216.   
  217.         br.Read(fieldNameBytes, 1, 10);  
  218.         fieldDescriptor.Name = name;   
  219.         fieldDescriptor.TypeChar = (char)br.ReadByte();  
  220.         br.ReadByte(); // reserved  
  221.         br.ReadByte(); // reserved  
  222.         br.ReadByte(); // reserved  
  223.         br.ReadByte(); // reserved  
  224.         fieldDescriptor.Length = br.ReadByte();  
  225.         fieldDescriptor.DecimalCount = br.ReadByte();  
  226.         br.ReadBytes(2); // work area id  
  227.         br.ReadByte(); // example  
  228.         br.ReadBytes(10); // reserved  
  229.         br.ReadByte(); // production mdx  
  230.   
  231.         return fieldDescriptor;  
  232.     }  
  233.     catch (Exception e)  
  234.     {  
  235.         if (string.IsNullOrWhiteSpace(fieldDescriptor.Name))  
  236.             throw new Exception($"Failed to read field descriptor #{fdNo + 1}", e);  
  237.         else  
  238.             throw new Exception($"Failed to read field descriptor #{fdNo + 1} ({fieldDescriptor.Name})", e);  
  239.     }  
  240. }  
Create a new class DbfFieldDescriptor.
  1. public class DbfFieldDescriptor  
  2. {  
  3.     public int No { getset; }  
  4.     public string Name { getset; }  
  5.     public char TypeChar { getset; }  
  6.     public int Length { getset; }  
  7.     public byte DecimalCount { getset; }  
  8.   
  9.     public string GetSqlDataType()  
  10.     {  
  11.         switch (TypeChar)  
  12.         {  
  13.             case 'C':  
  14.                 return $"VARCHAR({Length})";  
  15.             case 'I':  
  16.                 return "INT";  
  17.             case 'N':  
  18.                 return $"DECIMAL({Length + 1}, {DecimalCount})";  
  19.             case 'L':  
  20.                 return "BIT";  
  21.             case 'B':  
  22.                 return "BIT";  
  23.             case 'D':  
  24.                 return "DATETIME";  
  25.             case 'M':  
  26.                 return "VARCHAR(MAX)";  
  27.             case 'S':  
  28.                 return "VARCHAR(MAX)";  
  29.             case 'T':  
  30.                 return "DATETIME";  
  31.             case 'W'//?  
  32.                 return "VARCHAR(MAX)";  
  33.             case '0':  
  34.                 return "INT";  
  35.             case 'G':  
  36.                 return "VARCHAR(MAX)";  
  37.             case 'F':  
  38.                 return "FLOAT";  
  39.             case 'Y':  
  40.                 return "NUMERIC(18,4)";  
  41.             default:  
  42.                 throw new NotSupportedException();  
  43.         }  
  44.     }  
  45. }