在博客园上看到了一个博主用EF做大批量插入的时候,提出性能不佳的看法,在下面的评论区里,各位大神对博主的代码作出了各种的改进
当然,也不乏一些高级黑的言论,在评论区中也发现了一些不少的改进性的代码,个人感觉这篇代码还不错,就收集一下,以备后用
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel.DataAnnotations;
4 using System.Data;
5 using System.Data.SqlClient;
6 using System.Linq;
7 using System.Text;
8
9 namespace MMAS_Demo
10 {
11
12 public class DbContextExtension
13 {
14 System.Data.Common.DbConnection Connection = null;
15
16 public DbContextExtension(System.Data.Common.DbConnection connection)
17 {
18 Connection = connection;
19 }
20
21 public void BulkInsertAll<T>(IEnumerable<T> entities) //大数据保存,针对一次插入几千条数据的情况
22 {
23 entities = entities.ToArray();
24
25 string cs = Connection.ConnectionString;
26 var conn = new SqlConnection(cs);
27 conn.Open();
28
29 Type t = typeof(T);
30
31 var bulkCopy = new SqlBulkCopy(conn)
32 {
33 DestinationTableName = t.Name
34 };
35
36 var properties = t.GetProperties().Where(EventTypeFilter).ToArray();
37 var table = new DataTable();
38
39 foreach (var property in properties)
40 {
41 Type propertyType = property.PropertyType;
42 if (propertyType.IsGenericType &&
43 propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
44 {
45 propertyType = Nullable.GetUnderlyingType(propertyType);
46 }
47
48 table.Columns.Add(new DataColumn(property.Name, propertyType));
49 }
50
51 foreach (var entity in entities)
52 {
53 table.Rows.Add(properties.Select(
54 property => GetPropertyValue(
55 property.GetValue(entity, null))).ToArray());
56 }
57
58 bulkCopy.WriteToServer(table);
59 conn.Close();
60 }
61
62 private bool EventTypeFilter(System.Reflection.PropertyInfo p)
63 {
64 var attribute = Attribute.GetCustomAttribute(p,
65 typeof(AssociationAttribute)) as AssociationAttribute;
66
67 if (attribute == null) return true;
68 if (attribute.IsForeignKey == false) return true;
69
70 return false;
71 }
72
73 private object GetPropertyValue(object o)
74 {
75 if (o == null)
76 return DBNull.Value;
77 return o;
78 }
79 }
80 }