C#中如何将变量转为枚举类型?SqlBulkCopy映射报错问题
问题分析与解决方案
核心问题
- 泛型方法中误用
typeof(e):typeof仅接受类型名,而e是变量实例,无法直接获取目标枚举类型。 - 调用代码错误:枚举不能用
new创建实例,且传递Enum基类实例会导致Enum.GetNames无法识别具体枚举类型,触发参数异常。
修正方案一:用泛型参数指定枚举类型(推荐)
直接通过泛型参数传递枚举类型,无需传入枚举实例,简化方法逻辑:
修改后的泛型方法
public void CommandBulkInsertBuilder<Tp, TEnum>(Tp dataTable) where Tp : DataTable where TEnum : struct, Enum // C#7.3及以上支持,确保TEnum是枚举类型 { SqlBulkCopy sqlBulk = new SqlBulkCopy(_conString); DataTable dt = dataTable; // 获取目标枚举的所有字段名 List<string> databaseColumns = Enum.GetNames(typeof(TEnum)).ToList(); foreach (DataColumn column in dt.Columns) { if (databaseColumns.Contains(column.ColumnName)) { sqlBulk.ColumnMappings.Add(column.ColumnName, column.ColumnName); } } sqlBulk.DestinationTableName = $"dbo.Temp{typeof(TEnum).Name}"; sqlBulk.WriteToServer(dt); }
调用方式
如果编译时已知枚举类型,直接调用:
da.CommandBulkInsertBuilder<DataTable, TblDogs>(dt); da.CommandBulkInsertBuilder<DataTable, TblDogHealth>(dt); da.CommandBulkInsertBuilder<DataTable, TblDogPedigree>(dt);
如果枚举类型是运行时动态确定的,用反射调用:
var enumTypes = new List<Type> { typeof(TblDogs), typeof(TblDogHealth), typeof(TblDogPedigree) }; foreach (Type enumType in enumTypes) { var method = typeof(YourDataAccessClass).GetMethod(nameof(CommandBulkInsertBuilder)) .MakeGenericMethod(typeof(DataTable), enumType); method.Invoke(da, new object[] { dt }); }
修正方案二:保留枚举实例参数(不推荐)
如果必须通过枚举实例传递类型信息,修改方法从实例获取具体枚举类型,并修正调用代码的枚举实例创建方式:
修改后的方法
public void CommandBulkInsertBuilder<Tp>(Tp dataTable, Enum enumInstance) where Tp : DataTable { Type enumType = enumInstance.GetType(); if (!enumType.IsEnum) throw new ArgumentException("参数必须是枚举实例", nameof(enumInstance)); SqlBulkCopy sqlBulk = new SqlBulkCopy(_conString); DataTable dt = dataTable; List<string> databaseColumns = Enum.GetNames(enumType).ToList(); foreach (DataColumn column in dt.Columns) { if (databaseColumns.Contains(column.ColumnName)) { sqlBulk.ColumnMappings.Add(column.ColumnName, column.ColumnName); } } sqlBulk.DestinationTableName = $"dbo.Temp{enumType.Name}"; sqlBulk.WriteToServer(dt); }
修正后的调用代码
枚举不能用new创建实例,需使用枚举成员或默认值:
// 假设枚举有定义的成员,比如TblDogs.Id, TblDogs.Name等 List<Enum> enums = new List<Enum> { TblDogs.Id, TblDogHealth.Status, TblDogPedigree.PedigreeId }; foreach (Enum ee in enums) { da.CommandBulkInsertBuilder(dt, ee); }
关键错误点说明
typeof(e):typeof仅能接收类型标识符(如TEnum、int),不能接收变量,需替换为typeof(TEnum)或enumInstance.GetType()。new TblDogs():枚举类型不支持直接用new创建实例,需通过枚举成员、default(TblDogs)或类型转换获取实例。List<Enum>传递实例:此时编译时类型为Enum基类,需通过GetType()获取具体枚举类型,否则Enum.GetNames会因传入非枚举类型(Enum基类不是枚举)报错。
内容的提问来源于stack exchange,提问作者Aleksandar
相关产品推荐
相关产品推荐

