nasıl basit nesnenin bir List <> dan SqlBulkCopy ile büyük ekleme yapabilir>?SqlBulkCopy <
Özel IDataReader'ımı uygularım?
nasıl basit nesnenin bir List <> dan SqlBulkCopy ile büyük ekleme yapabilir>?SqlBulkCopy <
Özel IDataReader'ımı uygularım?
Basitçe nesnelerin listenizden create a DataTable ve veri tablosu geçerek SqlBulkCopy.WriteToServer
diyoruz.
Aşağıdaki yarayabilecek:
SqlBulkCopy ile maksimum performans için, uygun bir BatchSize ayarlamalısınız. 10.000 iyi çalışıyor gibi görünüyor - ama verileriniz için profil. SqlBulkCopyOptions.TableLock kullanırken
Ayrıca daha iyi sonuçlar gözlemlemek olabilir.
SqlBulkCopy performansının ilginç ve bilgilendirici analizler here bulunabilir. ObjectReader
da olmayan çalışabilirsiniz
using(var bcp = new SqlBulkCopy(connection))
using(var reader = ObjectReader.Create(data, "Id", "Name", "Description"))
{
bcp.DestinationTableName = "SomeTable";
bcp.WriteToServer(reader);
}
Not olun: FastMember ile
, hiç (performans daha-daha-iki katına benim testlerde,) DataTable
yoluyla gitmeye gerek kalmadan bunu yapabilirsiniz (muhtemelen ObjectReader
kendisi bunları belirtmek yoksa SqlBulkCopy
ait ColumnMappings
yönünü kullanmak istiyorum rağmen) genel kaynaklar ve önceden üye adlarını belirtmek için gerekli değildir.
Mükemmel kütüphane! Hemen şimdi denedim ve harika çalışıyor. – alex
Bunun birkaç ay öncesinden olduğunu biliyorum, ancak benzer bir sorun yaşıyorum. Önce DataTable'ı yüklemek çok uzun sürüyor, bu yüzden bu yöntemi kullanmak istedim. Bununla birlikte, params değişkeninde listelenen dizgiler, alttaki veri yapısının üzerinde durduğu nesneden sıraya göre kullanılan değişkenlerin gerçek isimleridir. – JNYRanger
Scratch - bunu anladım ve cevabı evet, bunlar nesnenin içindeki özelliklerin isimleridir. – JNYRanger
İlk olarak SqlBulkCopy
numaralı telefonu arayarak yapmaya çalıştığınız şeye bağlı olarak, Tablo Değerli Parametre (TVP) kullanmak daha mantıklı olabilir. Bir TVP kullanmak, herhangi bir özel türden bir koleksiyonda göndermeyi önemsiz kılar. Veriler akışa alınabilir, böylece DataTable
'dan (@Marc Gravell'in cevabında olduğu gibi) kaçınılabilir ve SqlBulkCopy
'u da önleyebilirsiniz. TVP'leri, TVP verisini geçmek için bir Depolanmış Prosedürü çağırdığınızda SQL Server'a ulaştığında verileri nasıl ele alacağınıza tamamen esneklik sağlar ve sadece INSERT
ile değil, her şeyi yapabileceğiniz bir Tablo Değişkeni olarak görünür. SqlBulkCopy
ile durum). Ayrıca, yeni oluşturulan IDENTITY
değerleri gibi verileri SqlDataReader
aracılığıyla geri alabilirsiniz. Bu yanıtla ilgili bir örnek ve bazı ek notlar ekledim: How can I insert 10 million records in the shortest time possible?. Ve birkaç yıl önce, SQL Server Central'da (ücretsiz kayıt gerekli), Streaming Data Into SQL Server 2008 From an Application'da bir makale yazdım. Bu raporda ayrıca, 3 milyondan başlayarak özel bir türden bir Genel Listede geçen bir çalışma örneği sunan bağlantılı bir cevaba da dikkat çekildi. satır metni dosyası.
partiye Geç ama Microsoft'tan bu EntityDataReader
sınıf eklerseniz işte bunu yapıyor bir AsDataReader()
uzatma yöntemi var: https://github.com/matthewschrager/Repository/blob/master/Repository.EntityFramework/EntityDataReader.cs
(örnek [List].AsDataReader()
uygulama :)
var connStr = "";
using (var connection = new SqlConnection(connStr))
{
var startTime = DateTime.Now;
connection.Open();
var transaction = connection.BeginTransaction();
try
{
//var connStr = connection.ConnectionString;
using (var sbCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.Default, transaction))
{
sbCopy.BulkCopyTimeout = 0;
sbCopy.BatchSize = 10000;
sbCopy.DestinationTableName = "Foobars";
var reader = Foobars.AsDataReader();
sbCopy.WriteToServer(reader);
}
transaction.Commit();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
transaction.Rollback();
}
finally
{
transaction.Dispose();
connection.Close();
var endTime = DateTime.Now;
Console.WriteLine("Upload time elapsed: {0} seconds", (endTime - startTime).TotalSeconds);
}
}
Geç partiye Ancak, bu EntityDataReader sınıfını eklerseniz, tam olarak bunu yapan bir AsDataReader() uzantısı yöntemi vardır: https: // github.com/matthewschrager/Repository/blob/master/Repository.EntityFramework/EntityDataReader.cs – RJB
(tam uygulama için aşağıdaki yeni cevaba bakın) – RJB