65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.96/5 (18投票s)

2011 年 12 月 9 日

CPOL
viewsIcon

95797

如何使用大容量插入与您的 LINQ-to-SQL 数据上下文

Linq-to-SQL 在很多方面都很出色,但在处理大量插入时表现不佳。 通过扩展数据上下文部分类,并添加以下代码就可以解决这个问题。 我也在 这里 写过关于这方面的内容。 您只需要像往常一样创建您的 LINQ 实体,然后调用 datacontext 上的 BulkInsertAll 方法。 另外,在执行大容量 插入 之前,不要将此 datacontext 用于其他任何操作。 我们用来创建 SQLConnectiondatacontext 的连接字符串,由于某种原因,在第一次使用后会丢失密码,这显然会使连接变得有些困难。

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;
    }
}
© . All rights reserved.