接下来放一个用SqlBulkCopy插入数据的例子,运用了泛型委托和反射。就当好好的运用这些知识。
public static void AddEntityByBulk(IList entitys,string TableName) where TEntity : class
{
using (context = new MyDbContext())
{
//接下来就是批量插入
using (var bulkCopy = new SqlBulkCopy((SqlConnection) context.Database.Connection))
{
bulkCopy.BatchSize = entitys.Count;
bulkCopy.DestinationTableName = TableName;
var table = new DataTable();
Type reccordType = typeof (TEntity);//获取模板类型
PropertyInfo[] propertys = reccordType.GetProperties();
foreach (PropertyInfo property in propertys)
{
if (!property.GetGetMethod().IsVirtual)
{
table.Columns.Add(property.Name, property.PropertyType);
}
}
foreach (var entity in entitys)
{
var dr = table.NewRow();
foreach (var property in propertys)
{
if (!property.GetGetMethod().IsVirtual)
dr[property.Name] = property.GetValue(entity,null);
}
table.Rows.Add(dr);
}
if (context.Database.Connection.State != System.Data.ConnectionState.Open)
{
context.Database.Connection.Open();
}
bulkCopy.WriteToServer(table);
context.Database.Connection.Close();
}
}
}
接下来主要是对反射部分的抽与总结:
1 Type reccordType = typeof (TEntity);
获取模板类型,无论是泛型还是实体类型,总之先获取他的类型格式,以方便反射内部的属性,字段以及方法。
2 PropertyInfo[] propertys = reccordType.GetProperties();
获取该类型的所有属性,切记,只是属性(就是后面有get;set;),方法是不会获取到的。这可以更好的操作数据。
3 property.GetGetMethod().IsVirtual
但是由于codefirst的实体类中的虽然都是属性,但是会存在自定义的类型,即为了标识与其他类的关系,比如一本书只属于一个出版社,那么实体类就会有一个出版社的属性,一个出版社有很多书,那么出版社的实体类就有一个属性标识着很多书的集合,但是这些都是反射所不需要的,幸好在创建这些属性时都是设置为virtual(感谢是这么设置的,不然区分都不容易),每个属性都有get和set方法(这两个就当作方法,虽然本来就是方法),要区分他们就可以使用property.GetGetMethod().IsVirtual,这个可以获取所有的get方法,获取set方法,当然也是可以的,只要判断他们是虚方法就好了,然后就可以区别他们了。
4 property.GetValue(entity,null);
该方法是为了获取某个实体在该属性下的值,就相当与一行记录的某一列的值,可以这么理解吧。
这只是一个小小封装,有什么更好的意见或者方法大家可以自己尝试尝试哦!!