使用 SQL 大容量复制与您的 LINQ-to-SQL 数据上下文






4.96/5 (18投票s)
如何使用大容量插入与您的 LINQ-to-SQL 数据上下文
Linq-to-SQL 在很多方面都很出色,但在处理大量插入时表现不佳。 通过扩展数据上下文部分类,并添加以下代码就可以解决这个问题。 我也在 这里 写过关于这方面的内容。 您只需要像往常一样创建您的 LINQ 实体,然后调用 datacontext
上的 BulkInsertAll
方法。 另外,在执行大容量 插入
之前,不要将此 datacontext
用于其他任何操作。 我们用来创建 SQLConnection
的 datacontext
的连接字符串,由于某种原因,在第一次使用后会丢失密码,这显然会使连接变得有些困难。
partial class MyDataContext
{
partial void OnCreated()
{
CommandTimeout = 5 * 60;
}
public void BulkInsertAll<T>(IEnumerable<T> entities)
{
entities = entities.ToArray();
string cs = Connection.ConnectionString;
var conn = new SqlConnection(cs);
conn.Open();
Type t = typeof(T);
var tableAttribute = (TableAttribute)t.GetCustomAttributes(
typeof(TableAttribute), false).Single();
var bulkCopy = new SqlBulkCopy(conn) {
DestinationTableName = tableAttribute.Name };
var properties = t.GetProperties().Where(EventTypeFilter).ToArray();
var table = new DataTable();
foreach (var property in properties)
{
Type propertyType = property.PropertyType;
if (propertyType.IsGenericType &&
propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
propertyType = Nullable.GetUnderlyingType(propertyType);
}
table.Columns.Add(new DataColumn(property.Name, propertyType));
}
foreach (var entity in entities)
{
table.Rows.Add(properties.Select(
property => GetPropertyValue(
property.GetValue(entity, null))).ToArray());
}
bulkCopy.WriteToServer(table);
conn.Close();
}
private bool EventTypeFilter(System.Reflection.PropertyInfo p)
{
var attribute = Attribute.GetCustomAttribute(p,
typeof (AssociationAttribute)) as AssociationAttribute;
if (attribute == null) return true;
if (attribute.IsForeignKey == false) return true;
return false;
}
private object GetPropertyValue(object o)
{
if (o == null)
return DBNull.Value;
return o;
}
}