I have these two classes:
public class Message
{
string Message;
string Code;
}
public class MessageInitializer
{
DataSet ds;
DataRow dr;
message[] ms;
}
I want to create a constructor in MessageInitializer like this:
MessageInitializer()
{
this.ms = new Message[ds.Tables[0].Rows.Count];
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
dr = ds.Tables[0].Rows[i];
ms[(string)dr.ItemArray[0]] = (string)dr.ItemArray[1];
}
}
But array's index must be int type. I have no idea how to work this out:
ms[(string)dr.ItemArray[0]] = (string)dr.ItemArray[1];
Update:
Code format is a string like this: [001-001-001], so I can't convert it to integer.
you don't need Message class any more. Using a dictionary as follows solves the problem :
public class MessageInitializer
{
DataSet ds;
DataRow dr;
Dictionary<string, string> ms;
public MessageInitializer()
{
this.ms = new Dictionary<string,string>(ds.Tables[0].Rows.Count);
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
dr = ds.Tables[0].Rows[i];
ms[(string)dr.ItemArray[0]] = (string)dr.ItemArray[1];
}
}
}
I hope this would be helpful.
If you just want to get a list of all the messages from the database, then you can use the code below. Note, List instead of Array. Easier to use and faster.
public class Message
{
string Message;
string Code;
}
public class MessageInitializer
{
DataSet ds;
DataRow dr;
List<Message> ms;
MessageInitializer()
{
this.ms = new List<Message>();
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
dr = ds.Tables[0].Rows[i];
ms.Add(new Message
{
Code = dr.ItemArray[0].ToString(),
Message = dr.ItemArray[1].ToString(),
});
}
}
}
You mentioned that you have couple million records. List will perform fine in case you want to access items sequestially. If you want to access items in a non-sequential manner, I suggest you use Dictionary instead (to improve search perfromance):
public class MessageInitializer
{
DataSet ds;
DataRow dr;
Dictionary<string, Message> ms;
MessageInitializer()
{
this.ms = new Dictionary<string, Message>();
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
dr = ds.Tables[0].Rows[i];
ms.Add(dr.ItemArray[0].ToString(), new Message
{
Code = dr.ItemArray[0].ToString(),
Message = dr.ItemArray[1].ToString(),
});
}
}
}
You can access message as follows:
var message = ms["001-001-001"];
It will be orders or magnitude faster than accessing a random List item:
var message - ms.First(x => x.Code == "001-001-001");
I think you just want build an array of messages from ds.Tables[0]
Code -
ms[i].Code = (string)dr.ItemArray[0];
Message -
ms[i].Message = (string)dr.ItemArray[1];
MessageInitializer()
{
this.ms = new Message[ds.Tables[0].Rows.Count];
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
dr = ds.Tables[0].Rows[i];
ms[i].Code= (string)dr.ItemArray[0];
ms[i].Message = (string)dr.ItemArray[1];
}
}
For better performance make use of Parallel.ForEach -
Parallel.ForEach(ds.Tables[0].AsEnumerable(), row => {
ms[i].Code= (string)row.ItemArray[0];
ms[i].Message = (string)row.ItemArray[1];
});
I think what you want to perform is the following:
public class Message
{
public string message { get; set; }
public string code { get; set; }
}
public class MessageInitializer
{
DataSet ds;
DataRow dr;
Message[] ms;
MessageInitializer()
{
this.ms = new Message[ds.Tables[0].Rows.Count];
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
dr = ds.Tables[0].Rows[i];
ms[i] = new Message
{
code = (string)dr.ItemArray[0],
message = (string)dr.ItemArray[1]
};
}
}
}
Related
I have a string like this:
"Product,Price,Condition
Cd,13,New
Book,9,Used
"
Which is being passed like this:
"Product,Price,Condition\r\Cd,13,New\r\nBook,9,Used"
How could I convert it to DataTable?
Trying to do it with this helper function:
DataTable dataTable = new DataTable();
bool columnsAdded = false;
foreach (string row in data.Split(new string[] { "\r\n" }, StringSplitOptions.None))
{
DataRow dataRow = dataTable.NewRow();
foreach (string cell in row.Split(','))
{
string[] keyValue = cell.Split('~');
if (!columnsAdded)
{
DataColumn dataColumn = new DataColumn(keyValue[0]);
dataTable.Columns.Add(dataColumn);
}
dataRow[keyValue[0]] = keyValue[1];
}
columnsAdded = true;
dataTable.Rows.Add(dataRow);
}
return dataTable;
However I don't get that "connecting cells with appropriate columns" part - my cells don't have ~ in string[] keyValue = cell.Split('~'); and I obviously get an IndexOutOfRange at DataColumn dataColumn = new DataColumn(keyValue[0]);
Based on your implementation, I have written the code for you, I have not tested it. But you can use the concept.
DataRow dataRow = dataTable.NewRow();
int i = 0;
foreach (string cell in row.Split(','))
{
if (!columnsAdded)
{
DataColumn dataColumn = new DataColumn(cell);
dataTable.Columns.Add(dataColumn);
}
else
{
dataRow[i] = cell;
}
i++;
}
if(columnsAdded)
{
dataTable.Rows.Add(dataRow);
}
columnsAdded = true;
You can do that simply with Linq (and actually there is LinqToCSV on Nuget, maybe you would prefer that):
void Main()
{
string data = #"Product,Price,Condition
Cd,13,New
Book,9,Used
";
var table = ToTable(data);
Form f = new Form();
var dgv = new DataGridView { Dock = DockStyle.Fill, DataSource = table };
f.Controls.Add(dgv);
f.Show();
}
private DataTable ToTable(string CSV)
{
DataTable dataTable = new DataTable();
var lines = CSV.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var colname in lines[0].Split(','))
{
dataTable.Columns.Add(new DataColumn(colname));
}
foreach (var row in lines.Where((r, i) => i > 0))
{
dataTable.Rows.Add(row.Split(','));
}
return dataTable;
}
You can split given string into flattened string array in one call. Then you can iterate through the array and populate list of objects.
That part is optional, since you can immediately populate DataTable but I think it's way easier (more maintainable) to work with strongly-typed objects when dealing with DataTable.
string input = "Product,Price,Condition\r\nCd,13,New\r\nBook,9,Used";
string[] deconstructedInput = input.Split(new string[] { "\r\n", "," }, StringSplitOptions.None);
List<Product> products = new List<Product>();
for (int i = 3; i < deconstructedInput.Length; i += 3)
{
products.Add(new Product
{
Name = deconstructedInput[i],
Price = Decimal.Parse(deconstructedInput[i + 1]),
Condition = deconstructedInput[i + 2]
});
}
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
public string Condition { get; set; }
}
So, products collection holds 2 objects which you can easily iterate over and populate your DataTable.
Note: This requires further checks to avoid possible runtime exceptions, also it is not dynamic. That means, if you have differently structured input it won't work.
DataTable dataTable = new DataTable();
dataTable.Columns.Add(new DataColumn(nameof(Product.Name)));
dataTable.Columns.Add(new DataColumn(nameof(Product.Price)));
dataTable.Columns.Add(new DataColumn(nameof(Product.Condition)));
foreach (var product in products)
{
var row = dataTable.NewRow();
row[nameof(Product.Name)] = product.Name;
row[nameof(Product.Price)] = product.Price;
row[nameof(Product.Condition)] = product.Condition;
dataTable.Rows.Add(row);
}
I have searched for a long time and tried different ways to solve this problem without any success.
My current program is as follows:
Web service: DAL, Controller and WebService(with web methods)
Windows form: Controller(receives the web service) and Form
I receive a string array in the DAL that I try to send through the web service to my Controller in the windows form program. But receive the error:
Cannot implicity convert type
'WindowsFormApplication.ServiceReference1.ArrayOfString' to
'System.Collections.Generic.List<string[]>'
Controller in form:
public List<string[]> GetAllEmployee()
{
return client.GetAllEmployee();
}
Webservice:
public List<string[]> GetAllEmployee()
{
return cont.GetAllEmployee();
}
DAL:
public List<string[]> GetAllEmployee()
{
GetConnection();
con.Open();
stmt = con.CreateCommand();
stmt.CommandText = "SELECT [No_],[First Name],[Last Name],[Initials],[Job Title],[E-Mail] FROM [CRONUS Sverige AB$Employee]";
OdbcDataReader reader = stmt.ExecuteReader();
List<string[]> allEmployee = new List<string[]>();
String[] cols = new string[5];
for (int i = 0; i < cols.Length; ++i)
{
cols[i] = reader.GetName(i);
}
allEmployee.Add(cols);
while (reader.Read())
{
string[] s = new string[cols.Length];
for (int i = 0; i < s.Length; ++i)
{
s[i] = reader.GetValue(i).ToString();
}
allEmployee.Add(s);
}
con.Close();
return allEmployee;
}
Controller:
public List<string[]> GetAllEmployee()
{
return dal.GetAllEmployee();
}
client:
ServiceReference1.WebService1SoapClient client = new ServiceReference1.WebService1SoapClient();
Your service returns the type WindowsFormApplication.ServiceReference1.ArrayOfString which needs to be explicitly converted to List<string> with ToList Method:
return dal.GetAllEmployee().ToList();
I have a csv file delimited with pipe(|). I am reading it using the following line of code:
IEnumerable<string[]> lineFields = File.ReadAllLines(FilePath).Select(line => line.Split('|'));
Now, I need to bind this to a GridView. So I am creating a dynamic DataTable as follows:
DataTable dt = new DataTable();
int i = 0;
foreach (string[] order in lineFields)
{
if (i == 0)
{
foreach (string column in order)
{
DataColumn _Column = new DataColumn();
_Column.ColumnName = column;
dt.Columns.Add(_Column);
i++;
//Response.Write(column);
//Response.Write("\t");
}
}
else
{
int j = 0;
DataRow row = dt.NewRow();
foreach (string value in order)
{
row[j] = value;
j++;
//Response.Write(column);
//Response.Write("\t");
}
dt.Rows.Add(row);
}
//Response.Write("\n");
}
This works fine. But I want to know if there is a better way to convert IEnumerable<string[]> to a DataTable. I need to read many CSVs like this, so I think the above code might have performance issues.
Starting from .Net 4:
use ReadLines.
DataTable FileToDataTable(string FilePath)
{
var dt = new DataTable();
IEnumerable<string[]> lineFields = File.ReadLines(FilePath).Select(line => line.Split('|'));
dt.Columns.AddRange(lineFields.First().Select(i => new DataColumn(i)).ToArray());
foreach (var order in lineFields.Skip(1))
dt.Rows.Add(order);
return dt;
}
(edit: instead this code, use the code of #Jodrell answer, This prevents double charging of the Enumerator).
Before .Net 4:
use streaming:
DataTable FileToDataTable1(string FilePath)
{
var dt = new DataTable();
using (var st = new StreamReader(FilePath))
{
// first line procces
if (st.Peek() >= 0)
{
var order = st.ReadLine().Split('|');
dt.Columns.AddRange(order.Select(i => new DataColumn(i)).ToArray());
}
while (st.Peek() >= 0)
dt.Rows.Add(st.ReadLine().Split('|'));
}
return dt;
}
since, in your linked example, the file has a header row.
const char Delimiter = '|';
var dt = new DataTable;
using (var m = File.ReadLines(filePath).GetEnumerator())
{
m.MoveNext();
foreach (var name in m.Current.Split(Delimiter))
{
dt.Columns.Add(name);
}
while (m.MoveNext())
{
dt.Rows.Add(m.Current.Split(Delimiter));
}
}
This reads the file in one pass.
Code below is me trying to do just that. It returns all rows but only like DEFAULT VALUES (0, empty string, empty date...) and "Allow Nulls" is false for all columns in my db table. I am truly stuck. I am still in process of learning c#, so if someone could please explain to me WHAT am I doing wrong here? Is there a better way to do this?
public List<XNarudzbe> GetXNarudzbe()
{
var listXnar = new List<XNarudzbe>();
using (SqlConnection NConnection = new SqlConnection(Params.ConnectionStr))
{
NConnection.Open();
using (var cmd = new SqlCommand("SELECT * FROM [dbo].[XDATA_NARUDZBE]", NConnection))
{
SqlDataReader reader = cmd.ExecuteReader();
int id = reader.GetOrdinal("ID");
int dt_get = reader.GetOrdinal("DT_GET");
int rn_datum = reader.GetOrdinal("RN_DATUM");
int datum = reader.GetOrdinal("DATUM");
int dt_stamp = reader.GetOrdinal("DT_STAMP");
int art_id = reader.GetOrdinal("ART_ID");
int cijena_k = reader.GetOrdinal("CIJENA_K");
int cijena_mp = reader.GetOrdinal("CIJENA_MP");
int cijena_vp = reader.GetOrdinal("CIJENA_VP");
int faktura = reader.GetOrdinal("FAKTURA");
int isporuceno = reader.GetOrdinal("ISPORUCENO");
int iznos_k = reader.GetOrdinal("IZNOS_K");
int iznos_p = reader.GetOrdinal("IZNOS_P");
int naruceno = reader.GetOrdinal("NARUCENO");
int narudzba = reader.GetOrdinal("NARUDZBA");
int otpremnica = reader.GetOrdinal("OTPREMNICA");
int pdv = reader.GetOrdinal("PDV");
int povrat_k = reader.GetOrdinal("POVRAT_K");
int povrat_p = reader.GetOrdinal("POVRAT_P");
int pp_id = reader.GetOrdinal("PP_ID");
int preporuka = reader.GetOrdinal("PREPORUKA");
int rabat = reader.GetOrdinal("RABAT");
int rn_id = reader.GetOrdinal("RN_ID");
int skart = reader.GetOrdinal("SKART");
int user_id = reader.GetOrdinal("USER_ID");
int var_n = reader.GetOrdinal("VAR_N");
int var_v = reader.GetOrdinal("VAR_V");
int veleprodaja = reader.GetOrdinal("VELEPRODAJA");
int vraceno = reader.GetOrdinal("VRACENO");
int isporuka_id = reader.GetOrdinal("ISPORUKA_ID");
int otpremljeno = reader.GetOrdinal("OTPREMLJENO");
int promjena = reader.GetOrdinal("PROMJENA");
int rj_id = reader.GetOrdinal("RJ_ID");
int zakljucano = reader.GetOrdinal("ZAKLJUCANO");
if (reader.HasRows)
{
while (reader.Read())
{
var recXNar = new XNarudzbe();
recXNar.id = reader["ID"] as decimal? ?? 0M; // reader.GetDecimal(id);
recXNar.dt_get = reader.GetDateTime(dt_get);
recXNar.rn_datum = reader.GetDateTime(rn_datum);
recXNar.datum = reader.GetDateTime(datum);
recXNar.dt_stamp = reader.GetDateTime(dt_stamp);
recXNar.art_id = reader.GetDecimal(art_id);
recXNar.cijena_k = reader.GetDecimal(cijena_k);
recXNar.cijena_mp = reader.GetDecimal(cijena_mp);
recXNar.cijena_vp = reader.GetDecimal(cijena_vp);
recXNar.faktura = reader.GetDecimal(faktura);
recXNar.isporuceno = reader.GetDecimal(isporuceno);
recXNar.iznos_k = reader.GetDecimal(iznos_k);
recXNar.iznos_p = reader.GetDecimal(iznos_p);
recXNar.naruceno = reader.GetDecimal(naruceno);
recXNar.narudzba = reader.GetDecimal(narudzba);
recXNar.otpremnica = reader.GetDecimal(otpremnica);
recXNar.pdv = reader.GetDecimal(pdv);
recXNar.povrat_k = reader.GetDecimal(povrat_k);
recXNar.povrat_p = reader.GetDecimal(povrat_p);
recXNar.pp_id = reader.GetDecimal(pp_id);
recXNar.preporuka = reader.GetDecimal(preporuka);
recXNar.rabat = reader.GetDecimal(rabat);
recXNar.rn_id = reader.GetDecimal(rn_id);
recXNar.skart = reader.GetDecimal(skart);
recXNar.user_id = reader.GetDecimal(user_id);
recXNar.var_n = reader.GetDecimal(var_n);
recXNar.var_v = reader.GetDecimal(var_v);
recXNar.veleprodaja = reader.GetDecimal(veleprodaja);
recXNar.vraceno = reader.GetDecimal(vraceno);
recXNar.isporuka_id = reader.GetString(isporuka_id);
recXNar.otpremljeno = reader.GetString(otpremljeno);
recXNar.promjena = reader.GetString(promjena);
recXNar.rj_id = reader.GetString(rj_id);
recXNar.zakljucano = reader.GetString(zakljucano);
listXnar.Add(recXNar);
}
}
reader.Close();
}
}
return listXnar;
}
There is a better way ( You need to just do it once and it will help in future). Derive a class from DbDataReader that will take sqldatareader in the constructor:
public class CustomReader : DbDataReader
{
private readonly SqlDataReader sqlDataReader;
//Set the sqlDataReader
public CustomReader(SqlDataReader sqlDataReader)
{
this.sqlDataReader = sqlDataReader;
//Cache the names
this.CacheColumns();
}
private Dictionary<string,int> nameOrdinals = new Dictionary<string, int>();
private void CacheColumns()
{
int fieldCount= this.sqlDataReader.FieldCount;
for (int i = 0; i <= fieldCount-1; i++)
{
string name=sqlDataReader.GetName(i);
nameOrdinals.Add(name,i);
}
}
public override object this[string name]
{
get
{
int ordinal=this.nameOrdinals[name];
return this.GetValue(ordinal);
}
}
//Custom implementation
public string GetString(string name)
{
int ordinal = this.nameOrdinals[name];
return this.GetString(ordinal);
}
//Custom implementation
public string GetString(string name,string defaultValue)
{
int ordinal = this.nameOrdinals[name];
if (this.IsDBNull(ordinal))
{
return defaultValue;
}
return this.GetString(ordinal);
}
//return from sqlDataReader
public override string GetString(int ordinal)
{
return sqlDataReader.GetString(ordinal);
}
public override void Close()
{
sqlDataReader.Close();
}
So what I have done is passed the SqlDataReader in custom class that can cache the column names with the positions. Then you are free to call the Custom implementation using the delegate sqldatareader or write your own functions on top - like I have done for string. Little bit of work initially but you can put all checks here like check for DbNull etc and return default values based on that.
SqlCommand sqlCommand = new SqlCommand("select * from cats",sqlConnection);
SqlDataReader reader = sqlCommand.ExecuteReader();
CustomReader customReader = new CustomReader(reader);
List<Cat> list = new List<Cat>();
while (customReader.Read())
{
Cat cat = new Cat();
cat.Id = customReader.GetString("id");
cat.Name = customReader.GetString("name");
list.Add(cat);
}
You may need to check the names of the columns coming back so may be store in lower case and then read in lower case. Your code doesnt need to do getordinal anymore and it is much cleaner as well.
There are several ways to do this using the SqlDataReader and DataTable....
IEnumerable<DataRow> list0 = dt.AsEnumerable();
OR
List<DataRow> list1 = new List<DataRow>(dt.Select());
OR
List<DataRow> list2 = dt.AsEnumerable().ToList();
For simple examples of DataTable take a look at this.....
http://www.nakdev.somee.com/#2&2AD97ECBE2AE41D08191F6E4C773D8A9&cs
Well it turns out that the code in my first post is OK! The mistake was in my POCO definition.
This is what caused the problem :
...
private DateTime _dt_get;
public DateTime dt_get
{
get { return _dt_get; }
set { value = _dt_get; } // <-- !!! insted of set { _dt_get = value; }
}
...
Thx for any help...
I have following string,
I want to convert it to DataTable
"Id,Name ,Dept\r\n1,Mike,IT\r\n2,Joe,HR\r\n3,Peter,IT\r\n"
I can create it using String.Split and iterating through collection.
But I need efficient way (using C# 4.0 features)
How to create table using LINQ or lambda.
I don't know if that what are you looking for :
string s = "Id,Name ,Dept\r\n1,Mike,IT\r\n2,Joe,HR\r\n3,Peter,IT\r\n";
DataTable dt = new DataTable();
string[] tableData = s.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var col = from cl in tableData[0].Split(",".ToCharArray())
select new DataColumn(cl);
dt.Columns.AddRange(col.ToArray());
(from st in tableData.Skip(1)
select dt.Rows.Add(st.Split(",".ToCharArray()))).ToList();
I Think this method will be useful. This method can be used for both CSVString or CsvFilePath. If you want to convert CsvFilePath then you have to specify first path has true else false.
public DataTable ConvertCsvStringToDataTable(bool isFilePath,string CSVContent)
{
//CSVFilePathName = #"C:\test.csv";
string[] Lines;
if (isFilePath)
{
Lines = File.ReadAllLines(CSVContent);
}
else
{
Lines = CSVContent.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
}
string[] Fields;
Fields = Lines[0].Split(new char[] { ',' });
int Cols = Fields.GetLength(0);
DataTable dt = new DataTable();
//1st row must be column names; force lower case to ensure matching later on.
for (int i = 0; i < Cols; i++)
dt.Columns.Add(Fields[i].ToLower(), typeof(string));
DataRow Row;
for (int i = 1; i < Lines.GetLength(0); i++)
{
Fields = Lines[i].Split(new char[] { ',' });
Row = dt.NewRow();
for (int f = 0; f < Cols; f++)
Row[f] = Fields[f];
dt.Rows.Add(Row);
}
return dt;
}
using System;
using System.Xml;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public static string DataTableToString(DataTable dtData)
{
string sData = null;
StringBuilder sBuffer = null;
string Token = null;
int i = 0;
int j = 0;
sBuffer = new StringBuilder();
sBuffer.Append(#"<TABLE>");
sBuffer.Append(#"<TR>");
foreach (DataColumn Col in dtData.Columns)
{
sBuffer.Append(#"<TH ColType='")
.Append(Convert.ToString(Col.DataType))
.Append(#"'>")
.Append(Col.ColumnName.Replace("&", ""))
.Append(#"</TH>");
}
sBuffer.Append(#"</TR>");
i = 0;
foreach (DataRow rw in dtData.Rows)
{
sBuffer.Append(#"<TR>");
j = 0;
foreach (DataColumn Col in dtData.Columns)
{
if (!Convert.IsDBNull(rw[Col.ColumnName]))
{
Token = Convert.ToString(rw[Col.ColumnName]);
}
else
{
Token = null;
}
sBuffer.Append(#"<TD>").Append(Token).Append(#"</TD>");
j++;
}
sBuffer.Append(#"</TR>");
i++;
}
sBuffer.Append(#"</TABLE>");
sData = sBuffer.ToString();
return sData;
}
public static DataTable StringToDataTable(string sXmlData)
{
DataTable dtData = null;
XmlDocument xmlDoc = null;
XmlNode RootNode = null;
XmlNodeList TRList = null;
XmlNodeList THList = null;
XmlNodeList TDList = null;
int i = 0;
int j = 0;
XmlAttribute DataTypeAttrib = null;
string sDataType = null;
DataColumn Col = null;
Type ColType;
string Token = null;
DataRow newRw = null;
xmlDoc = new XmlDocument();
xmlDoc.LoadXml(sXmlData);
RootNode = xmlDoc.SelectSingleNode("/TABLE");
if (RootNode != null)
{
dtData = new DataTable();
i = 0;
TRList = RootNode.SelectNodes("TR");
foreach (XmlNode TRNode in TRList)
{
if (i == 0)
{
THList = TRNode.SelectNodes("TH");
foreach (XmlNode THNode in THList)
{
DataTypeAttrib = THNode.Attributes["ColType"];
sDataType = DataTypeAttrib.Value;
ColType = Type.GetType(sDataType);
Col = new DataColumn(THNode.InnerText, ColType);
if (!dtData.Columns.Contains(Col.ColumnName))
{
dtData.Columns.Add(Col);
}
}
}
else
{
newRw = dtData.NewRow();
j = 0;
TDList = TRNode.SelectNodes("TD");
foreach (XmlNode TDNode in TDList)
{
ColType = dtData.Columns[j].DataType;
Token = TDNode.InnerText;
if (!string.IsNullOrEmpty(Token))
{
try
{
newRw[j] = Convert.ChangeType(Token, ColType);
}
catch
{
if (ColType == typeof(DateTime))
{
newRw[j] = DateTime.ParseExact(Token, "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
}
}
}
else
{
newRw[j] = Convert.DBNull;
}
j++;
}
dtData.Rows.Add(newRw);
}
i++;
}
}
return dtData;
}