簡體   English   中英

使用 linq-to-sql 批量插入

[英]bulk insert with linq-to-sql

我有一個看起來像這樣的查詢:

using (MyDC TheDC = new MyDC())
{
   foreach (MyObject TheObject in TheListOfMyObjects)
   {
      DBTable TheTable = new DBTable();

      TheTable.Prop1 = TheObject.Prop1;
      .....
      TheDC.DBTables.InsertOnSubmit(TheTable);

   }
   TheDC.SubmitChanges();
}

此查詢基本上使用 linq-to-sql 將列表插入到數據庫中。 現在我在網上看到 L2S 不支持批量操作。 我的查詢是通過一次插入每個元素還是在一次寫入中插入所有元素?

感謝您的澄清。

我修改了以下鏈接中的代碼以提高效率並在我的應用程序中使用它。 這非常方便,因為您可以將它放在當前自動生成的類之上的部分類中。 而不是InsertOnSubmit將實體添加到列表,而不是SubmitChanges調用YourDataContext.BulkInsertAll(list)

http://www.codeproject.com/Tips/297582/Using-bulk-insert-with-your-linq-to-sql-datacontex

partial void OnCreated()
{
    CommandTimeout = 5 * 60;
}

public void BulkInsertAll<T>(IEnumerable<T> entities)
{                        
    using( var conn = new SqlConnection(Connection.ConnectionString))
    {
        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 => property.GetValue(entity, null) ?? DBNull.Value
                ).ToArray());
        }

        bulkCopy.WriteToServer(table);
    }                                               
}

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;
}

術語Bulk Insert通常是指 SQL Server 特定的基於超快速 bcp 的SqlBulkCopy實現。 它建立在IRowsetFastLoad 之上

任何情況下,Linq-2-SQL 都不會使用此機制實現插入。

如果您需要將數據批量加載到 SQL Server 中並且需要它的速度,我建議使用 SqlBulkCopy 手動編碼。

Linq-2-SQL 將嘗試執行一些優化以加速多個插入,但是它仍然無法滿足許多微 ORM(即使我知道沒有實現 SqlBulkCopy 的微 ORM)

它將為每條記錄生成一個插入語句,但會將它們全部發送到單個批處理中並在單個事務中運行。

這就是循環外的 SubmitChanges() 所做的。

如果你把它移到里面,那么循環中的每次迭代都會轉到服務器進行 INSERT 並在它自己的事務中運行。

我不相信有任何方法可以觸發 SQL BULK INSERT。

LINQ 單從列表插入:

                int i = 0;
                foreach (IPAPM_SRVC_NTTN_NODE_MAP item in ipapmList)
                {
                    ++i;
                    if (i % 50 == 0)
                    {
                        ipdb.Dispose();
                        ipdb = null;
                        ipdb = new IPDB();
                        // .NET CORE
                        //ipdb.ChangeTracker.AutoDetectChangesEnabled = false; 
                        ipdb.Configuration.AutoDetectChangesEnabled = false;
                    }

                    ipdb.IPAPM_SRVC_NTTN_NODE_MAP.Add(item);
                    ipdb.SaveChanges();
                }                 

我建議你看看 N.EntityFramework.Extension。 它是 EF 6 的基本批量擴展框架,可在 Nuget 上獲得,源代碼可在 MIT 許可下在 Github 上獲得。

Install-Package N.EntityFramework.Extensions

https://www.nuget.org/packages/N.EntityFramework.Extensions

安裝后,您可以直接在 DbContext 實例上直接使用 BulkInsert() 方法。 它支持 BulkDelete、BulkInsert、BulkMerge 等。

批量插入()

var dbcontext = new MyDbContext();  
var orders = new List<Order>();  
for(int i=0; i<10000; i++)  
{  
   orders.Add(new Order { OrderDate = DateTime.UtcNow, TotalPrice = 2.99 });  
}  
dbcontext.BulkInsert(orders);  

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM