因为要使用SqlBulkCopy批量插入
@灬丶: 现在执行需要多长时间?
@会长: 10秒?
@灬丶: 10秒倒10万也可以接受吧
@会长: 主要是list转datatable太耗时,因为用的反射,太慢了
@灬丶: 不用反射行不行,如果字段名是已知的,我猜字段名就是已知的吧。否则你们的数据库表难道是跟着字段名自动创建的?
@会长: 那也要把list转为datable的,因为最list是通过一些逻辑处理后台得到的
@灬丶: 转也不一定用反射,你们为什么用反射,为了得到datatable的列名吗?根据list中的元素的属性名来反射出datatable的列名?我觉得可以把列名写死就好了。
@会长: 得到列表,还要把list里面的数一条一条转为DataRow
@灬丶: 那也不用反射,看不懂,建议上个代码看看
@会长 foreach (T itemModel in listModels)
{
DataRow dataRow = dataTable.NewRow();
foreach (PropertyInfo item in propInfoArr)
{
string propName = item.Name;
if (listProperties.Contains(propName))
{
var queryResult = from n in dEnum
where n.Key == item.Name
select n;
//枚举集合中包含与当前属性名相同的项
if (queryResult.Count() > 0)
{
object temp = item.GetValue(itemModel, null);
//将字符串转换为枚举对象
var i = (int)Enum.Parse(queryResult.FirstOrDefault().Value, temp.ToString());
if (temp != null)
dataRow[propName] = temp;
}
else
{
object temp = item.GetValue(itemModel, null);
if (temp != null)
dataRow[propName] = temp;
}
}
}
dataTable.Rows.Add(dataRow);
}:
就是这样的
@灬丶: 我大概了解你们的需求了:把不可预知其所包含元素的属性名称的各种List插入到数据库,要求是如果元素的属性名称和数据库字段名称一致,则将其值插入到数据库,不知道我猜的是否正确
@会长: 对
@灬丶: 方法一:如果传过来的List种类是有限的,比如只有10个,那么就分别写10个类来转为datatable,这样就不用反射了。
方法二:你们数据库表是已经存在的吧,那就说明其实字段名称是已知的了。把所有要导入的数据类型继承于同一个父类,这个父类的属性和数据库表的字段名称对应上就好了。就是把那个泛型参数T限定为这个类的子类。
建议试试不用反射时的速度
写死吗?
@灬丶: 是的,至少为了确认是否是反射的原因
@dudu: 我调试了,生成DataTable大概耗了7秒左右
@灬丶: 难道你在10万次循环中每次都进行反射操作?
@dudu: 会有GetValue方法还有Pares方法,我猜想可能是装箱拆箱次数太多了
@灬丶: 你可以写代码测试,即使10万次装箱拆箱,也不会耗时7秒左右
https://www.cnblogs.com/yanglang/p/7778158.html
EF批量批入就行了, 为什么一定要转datatable呢
用的不是EF,是IBatis,但是为了提高批量插入的速度,就用了SqlBulkCopy
list本身就是可以反射获取name,value的,直接比对生成sql就可以吧,转成datatable干嘛
我感觉问题想复杂了,换个思路再想想
你还可以通过构建动态表达式树来转换,非常快,我这里30万数据转换加SqlBulkCopy插入数据总共约7秒
有构建动态表达式树来转换的教程吗?