我有幾列DataTable。列數是動態的,但它們都是字符串。 我需要將DataTable的字段從字符串轉換爲DataType,這將是該列中所有行的最佳匹配。C#更改DataTable列數據類型
實施例:
如果在一列中的所有行都是數字,然後改變該列數的數據類型;或者如果值是日期則返回DateTime;否則留作字符串。
這怎麼辦?我知道我必須創建一個新的DataTable。
我有幾列DataTable。列數是動態的,但它們都是字符串。 我需要將DataTable的字段從字符串轉換爲DataType,這將是該列中所有行的最佳匹配。C#更改DataTable列數據類型
實施例:
如果在一列中的所有行都是數字,然後改變該列數的數據類型;或者如果值是日期則返回DateTime;否則留作字符串。
這怎麼辦?我知道我必須創建一個新的DataTable。
這裏是我將如何做它的大綱。基本上使用基本類型的TryParse方法來確定最高計數。然後添加一個新類型的新列,儘可能多地轉換值。無法轉換的部分將保留爲DBNull.Value。
public class TypeCount {
public int IntCount;
public int LongCount;
public int DoubleCount;
public int DecimalCount;
public int DateCount;
// etc;
// provide your own logic to determine the best type
public Type BestType {
get {
int[] counts = new int[] { IntCount, LongCount, DoubleCount, DecimalCount, DateCount };
Type[] types = new Type[] { typeof(int), typeof(long), typeof(double), typeof(decimal), typeof(DateTime) };
Type bt = typeof(String);
int max = 0;
for (int i = 0; i < counts.Length; i++) {
if (counts[i] > max) {
bt = types[i];
max = counts[i];
}
}
return bt;
}
}
}
public static void TryParse(String s, NumberStyles ns, DateTimeStyles dts, IFormatProvider fp, String[] dateFormats, TypeCount counts) {
if (String.IsNullOrEmpty(s))
return;
long l;
int i;
double d;
decimal m;
// could test byte and short too if needed
if (int.TryParse(s, ns, fp, out i)) {
counts.IntCount++;
counts.LongCount++; // if int parses, then long also parses
}
else if (long.TryParse(s, ns, fp, out l))
counts.LongCount++;
// etc.
foreach (String f in dateFormats) {
DateTime date;
if (DateTime.TryParseExact(s, f, fp, dts, out date))
counts.DateCount++;
}
}
public static void ConvertColumns(DataTable table) {
IFormatProvider fp = CultureInfo.InvariantCulture;
NumberStyles ns = NumberStyles.Any;
DateTimeStyles dts = DateTimeStyles.None;
String[] dateFormats = new String[] { "yyyy-MM-dd", "MM/dd/yyyy" };
for (int i = 0; i < table.Columns.Count; i++) {
DataColumn col = table.Columns[i];
if (col.DataType != typeof(String))
continue;
TypeCount counts = new TypeCount();
for (int j = 0; j < table.Rows.Count; j++) {
String s = table.Rows[j][col] as String;
TryParse(s, ns, dts, fp, dateFormats, counts);
}
Type bestType = counts.BestType;
DataColumn temp = null;
if (bestType == typeof(int)) {
temp = table.Columns.Add("temp", typeof(int));
for (int j = 0; j < table.Rows.Count; j++) {
int val = 0;
String s = table.Rows[j][col] as String;
if (int.TryParse(s, ns, fp, out val))
table.Rows[j][temp] = val;
}
}
//else if (bestType == ...) {}
if (temp != null) {
temp.SetOrdinal(col.Ordinal);
table.Columns.Remove(col);
temp.ColumnName = col.ColumnName;
}
}
}
這是您嘗試執行的相當危險的操作。所有你需要的是一個單一的不可預知的值,你將會有一個異常,並且測試每個單元格的價值會非常昂貴。不知道你在試圖完成什麼,我建議 1.測試每列中的所有單元格,以瞭解您需要什麼類型(非常昂貴) 2.在每列中創建具有正確DataType的新DataTable,然後從舊的。與測試相比,這將是閃電fas