Inserción masiva de datos en la tabla de SQL Server desde un file de text delimitado usando c #

Tengo un file de text delimitado por tabuladores. El file tiene alnetworkingedor de 100MB. Quiero almacenar datos de este file en la tabla del server SQL. El file contiene 1 millón de loggings cuando se almacena en el server sql. ¿Cuál es la mejor manera de lograr esto?

Puedo crear en la tabla de datos de Momory en c # y luego upload el mismo al server sql, pero en este caso cargará todo el file de 100 MB en la memory. ¿Qué pasa si el tamaño del file aumenta?

No hay problema; CsvReader manejará la mayoría de los formattings de text delimitados, e implementa IDataReader , por lo que se puede usar para alimentar un SqlBulkCopy . Por ejemplo:

 using (var file = new StreamReader(path)) using (var csv = new CsvReader(file, true)) // true = first row is headers using (var bcp = new SqlBulkCopy(connectionString)) { bcp.DestinationTableName = "Foo"; bcp.WriteToServer(csv); } 

Tenga en count que CsvReader tiene muchas opciones, más event handling files más sutil (especificando las reglas del delimitador, etc.). SqlBulkCopy es la API de carga masiva de alto performance, muy eficiente. Esta es una API de lectura / escritura en time real; no carga todos los datos en la memory a la vez.

Debe leer el file línea por línea, para que no tenga que cargar toda la línea en la memory:

 using (var file = System.IO.File.OpenText(filename)) { while (!file.EndOfStream) { string line = file.ReadLine(); // TODO: Do your INSERT here } } 

* Actualización *

" Esto hará que 1 millón de commands de inserción por separado para el server sql. ¿Hay alguna manera de hacerlo a granel "

Podría usar consultas parametrizadas, que aún emitiría inserciones de 1M, pero aún sería bastante rápido.

Alternativamente, puede usar SqlBulkCopy , pero eso será bastante difícil si no desea usar bibliotecas de terceros. Si está más dispuesto a la licencia MS, podría usar el lector de datos de entidad LINQ (distribuido bajo la licencia Ms-PL), que proporciona el método de extensión AsDataReader :

 void MyInsertMethod() { using (var bulk = new SqlBulkCopy("MyConnectionString")) { bulk.DestinationTableName = "MyTableName"; bulk.WriteToServer(GetRows().AsDataReader()); } } class MyType { public string A { get; set; } public string B { get; set; } } IEnumerable<MyType> GetRows() { using (var file = System.IO.File.OpenText("MyTextFile")) { while (!file.EndOfStream) { var splitLine = file.ReadLine().Split(','); yield return new MyType() { A = splitLine[0], B = splitLine[1] }; } } } 

Si no desea utilizar el código de licencia de MS tampoco, puede implementar IDataReader usted mismo, pero eso será un PITA. Tenga en count que el manejo CSV anterior ( Split(',') ) no es en absoluto robusto, y también que los nombres de columna en la tabla deben ser los mismos que los nombres de propiedad en MyType . TBH, te recomiendo que vayas con la respuesta de Marc en este caso