2009-01-28 148 views
10

Estoy comenzando un proyecto con asp.net visual studio 2008/SQL 2000 (2005 en el futuro) usando C#.importar archivo csv/excel en la base de datos sql asp.net

La parte engañosa para mí es que el esquema de DB existente cambia a menudo y las columnas de los archivos de importación tendrán que coincidir con el esquema db existente ya que pueden no coincidir uno a uno en los nombres de las columnas. (Hay una tabla de búsqueda que proporciona el esquema de tablas con los nombres de columna que usaré)

Estoy explorando diferentes formas de abordar esto y necesito algunos consejos de expertos. ¿Hay algún control o marco existente que pueda aprovechar para hacer algo de esto?

Hasta ahora he explorado el control FileUpload .NET, así como algunos controles de carga 3er partido para llevar a cabo la carga como SlickUpload pero los archivos subidos debe ser < 500mb

siguiente parte es la lectura de mi CSV/Excel y analizándolo para que se muestre al usuario, de modo que puedan coincidir con nuestro esquema db. Vi CSVReader y otros pero para Excel es más difícil ya que necesitaré soportar diferentes versiones.

Esencialmente El usuario que realiza esta importación insertará y/o actualizará varias tablas de este archivo de importación. Existen otros requisitos más avanzados, como la coincidencia de registros pero y la vista previa de los registros de importación, pero deseo entender primero cómo hacerlo.

Actualización: terminé usando csvReader con LumenWorks.Framework para cargar los archivos csv.

Respuesta

1

Estoy usando csvReader de LumenWorks.Framework para cargar e importar los archivos csv en una tabla sql y una DataTable en la memoria que creo basada en las columnas importadas

También hago que el usuario correlacione los campos en la interfaz de usuario y proceda a validar y preparar los datos para la importación etiquetando cada registro como inserción/actualización/error. Luego creo/lleno un DataSet fuertemente tipado para cada tabla que se verá afectada y construyo las consultas de inserción/actualización para el método Enterprise Library UpdateDataset().

Luego presento la transacción para insertar/actualizar la base de datos. -

La asignación es una cuadrícula con 4 columnas. (importar nombre de campo, tabla de destino, nombre de campo de destino, ignorar, estado de coincidencia), con la tabla de destino y los nombres de campo que seleccionan qué actualización se basa en la tabla seleccionada. Yo llene dinámicamente los seleccionados. Inicialmente, seleccione combo se rellena con 1 valor si se encuentra la coincidencia, o seleccione si no lo está. ignorar le permite al usuario ignorar el campo. el estado del partido es si un campo fue mapeado automáticamente

5

Puede crear fácilmente un IDataReader sobre un archivo Excel o CSV (consulte http://support.microsoft.com/kb/316934).

¿Está utilizando SQL Server como motor de base de datos? De ser así, puede usar la clase SqlBulkCopy (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx) para tomar eficientemente su IDataReader, asignar columnas según corresponda y almacenar los resultados en su base de datos.

+0

sí, estoy usando sql server 2000 pero también necesita ser compatible con sql server 2005. No estoy familiarizado con SqlBulkCopy y analizaré esto. Me imagino que necesitaría usar algo más para poder actualizar – kiev

+0

Ah, cierto. Entonces, ¿necesita hacer insertos y actualizaciones? SqlBulkCopy es ideal para insertar eficientemente una gran cantidad de datos en su base de datos, pero no maneja las actualizaciones directamente. Puede resolver esto con una tabla de etapas y algunos SQL adicionales para mover datos a la tabla que realmente desea modificar. –

3

Sospecho que pueden existir algunas herramientas robustas y flexibles para ayudarlo con esta aplicación potencialmente muy compleja que, afortunadamente, alguien le indicará.

Mientras tanto, esta es una función que he encontrado útil para encubrir un archivo de Excel en una DataTable. Esta versión solo busca la primera hoja de trabajo. Podría servir como punto de partida. Para algo similar con archivos csv solo debería requerir la modificación de la cadena de conexión.

public static DataTable GetDataTableFromExcel(string SourceFilePath) 
{ 
    string ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + 
           "Data Source=" + SourceFilePath + ";" + 
           "Extended Properties=Excel 8.0;"; 

    using (OleDbConnection cn = new OleDbConnection(ConnectionString)) 
    { 
     cn.Open(); 

     DataTable dbSchema = cn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null); 
     if (dbSchema == null || dbSchema.Rows.Count < 1) 
     { 
      throw new Exception("Error: Could not determine the name of the first worksheet."); 
     } 

     string WorkSheetName = dbSchema.Rows[0]["TABLE_NAME"].ToString(); 

     OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM [" + WorkSheetName + "]", cn); 
     DataTable dt = new DataTable(WorkSheetName); 

     da.Fill(dt); 

     return dt; 
    } 
} 
+0

Desafortunadamente, esto no funcionará en las máquinas x64 porque jet existe solo para la plataforma x86. – Alex

8

Mira la excelente biblioteca FileHelpers - Existe un article on CodeProject al respecto, y se aloja here.

Es C# puro, y puede importar prácticamente cualquier archivo plano, CSV, y también trata con Excel. La importación es totalmente configurable; puede definir cosas como delimitadores, filas y/o columnas para omitir, y así sucesivamente, muchas opciones.

Lo he utilizado con éxito en varios proyectos y simplemente funciona sin problemas, muy recomendable.

+0

Gracias por el enlace Marc, mirando FileHelpers Veo que necesito definir una clase que corresponda al registro en el archivo fuente/detinación que necesito ser dinámico. Debido a que mis archivos CSV o Excel no tendrán el mismo formato, será necesario que coincidan con mis columnas de destino. – kiev

+0

Bien, veo tu problema, sin embargo, no tengo idea de cómo podrías resolverlo tan fácilmente :-(Algo totalmente dinámico ... ¡no es nada fácil de hacer! Buena suerte con tu búsqueda. –

1

FileHelpers es tu amigo. Lo he utilizado felizmente para varios proyectos y me ha ahorrado mucha pena y trabajo

Cuestiones relacionadas