如何动态创建类的属性

6

我使用了以下代码,使用SqlBulkCopy将Excel表格导入SQL表格。如何删除映射器类并动态创建列?

using SQL;

namespace Reader
{
    Public partial class Form1 :Form
    {
        /// <summary>
        /// Import Excel document into the SQL Database and Datagridview
        /// </summary>
        private void ImportExcel_Click(object sender, EventArgs e)
        {
            try
            {
                using (OpenFileDialog ImportExcelFileDialog = new OpenFileDialog() { Filter = "Excel Workbook|*.xlsx|Excel 97 -2003 Workbook|*.xls" })
                {
                    if (ImportExcelFileDialog.ShowDialog() == DialogResult.OK)
                    {
                        using (var stream = File.Open(ImportExcelFileDialog.FileName, FileMode.Open, FileAccess.Read))
                        {
                            using (IExcelDataReader Reader = ExcelReaderFactory.CreateReader(stream))
                            {
                                DataSet result = Reader.AsDataSet(new ExcelDataSetConfiguration()
                                {
                                    ConfigureDataTable = (_) => new ExcelDataTableConfiguration() { UseHeaderRow = true }
                                });
                                SqlConnection Connection = new SqlConnection(SQL_Commands._Connectionstring);
                                Connection.Open();

                                //SqliteDatabase[3] will give the table name that is used in SQLExpress
                                sqlcommands.DeleteTable(SqliteDatabase[3]);

                                //this is created from a SQL Query file there is only one column and that is ID
                                sqlcommands.RecreateDatabase(Connection);

                                //Get result from Excel file and create a Table from it.
                                tableCollection = result.Tables;
                                DataTable dt = tableCollection[SqliteDatabase[3]];

                                //Create columns in SQL Database 
                                foreach(DataColumn column in dt.Columns)
                                {
                                    if(column.ColumnName != "ID")
                                    {
                                        string columnName = "[" + column.ColumnName + "]";
                                        sqlcommands.AddColumn(columnName, SQLite.SqliteDatabase[3], "Text");
                                    }
                                }

                                //write already the values to datagridview 
                                InstrumentsBindingSource.DataSource = dt;

                                //Convert Datatable to IEnumerable(Instruments is a Mapper class)
                                var parts = BulkHelper.DataTableToIEnumerable<Instruments>(dt);
                                sqlcommands.ImportToExcel(parts, Connection);
                                sqlcommands.UpdateTableTotal(SQLite.SqliteDatabase[3], InstrumentsBindingSource, dataGridView1);
                            }
                        }
                    }
                }
            }
            catch (Exception EX)
            {
                MessageBox.Show(EX.ToString(), "Import Excel Sheet", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }
}

将DataTable转换为IEnumerable

namespace SQL
{
    public static class BulkHelper
    {
        public static IEnumerable<T> DataTableToIEnumerable<T>(this DataTable table) where T : class, new()
        {
            try
            {
                var objType = typeof(T);
                ICollection<PropertyInfo> properties;

                lock (_Properties)
                {
                    if (!_Properties.TryGetValue(objType, out properties))
                    {
                        properties = objType.GetProperties().Where(property => property.CanWrite).ToList();
                        _Properties.Add(objType, properties);
                    }
                }

                var list = new List<T>(table.Rows.Count);

                foreach (var row in table.AsEnumerable().Skip(1))
                {
                    var obj = new T();

                    foreach (var prop in properties)
                    {
                        try
                        {
                            var propType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
                            var SafeValue = row[prop.Name] == null ? null : Convert.ChangeType(row[prop.Name], propType);

                            prop.SetValue(obj, SafeValue, null);
                        }
                        catch
                        {
                            // ignored
                        }
                    }
                    list.Add(obj);
                }
                return list;
            }
            catch
            {
                return Enumerable.Empty<T>();
            }
        }
    }
}

创建BulkData并将其写入SQL表中
namespace SQL
{
    public class SQL_Commands
    {
        public void ImportToExcel(IEnumerable<Instruments> Parts, SqlConnection connection)
        {
            try
            {
                var bulkcopy = new SqlBulkCopy(connection);
                bulkcopy.DestinationTableName = "Instruments";
                bulkcopy.ColumnMappings.Add("Tag", "Tag");
                bulkcopy.ColumnMappings.Add("Area", "Area");
                bulkcopy.ColumnMappings.Add("Number", "Number");
                bulkcopy.ColumnMappings.Add("Tag_Name", "Tag_Name");
                bulkcopy.ColumnMappings.Add("Component_Description", "Component_Description");
                bulkcopy.ColumnMappings.Add("Function", "Function");
                bulkcopy.ColumnMappings.Add("Brand", "Brand");
                bulkcopy.ColumnMappings.Add("Type", "Type");
                bulkcopy.ColumnMappings.Add("M_Connection", "M_Connection");
                bulkcopy.ColumnMappings.Add("E_Connection", "E_Connection");
                bulkcopy.ColumnMappings.Add("Range", "Range");
                bulkcopy.ColumnMappings.Add("Remark", "Remark");
                bulkcopy.ColumnMappings.Add("Ordering_Code", "Ordering_Code");
                bulkcopy.ColumnMappings.Add("Panel", "Panel");
                bulkcopy.ColumnMappings.Add("DI", "DI");
                bulkcopy.ColumnMappings.Add("DO", "DO");
                bulkcopy.ColumnMappings.Add("AI", "AI");
                bulkcopy.ColumnMappings.Add("AO", "AO");
                bulkcopy.ColumnMappings.Add("Ethernet", "Ethernet");
                bulkcopy.ColumnMappings.Add("ASI", "ASI");

                using (var datareader = new ObjectDataReader<Instruments>(Parts))
                {
                    bulkcopy.WriteToServer(datareader);
                }
            }
            catch (Exception EX)
            {
                MessageBox.Show(EX.ToString(), "InsertBulk", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }
}

映射器类

namespace SQL
{
    public class Instruments
    {
        public string Tag { get; set; }
        public string Area { get; set; }
        public string Number { get; set; }
        public string Tag_Name { get; set; }
        public string Component_Description { get; set; }
        public string Function { get; set; }
        public string Brand { get; set; }
        public string Type { get; set; }
        public string M_Connection { get; set; }
        public string E_Connection { get; set; }
        public string Range { get; set; }
        public string Remark { get; set; }
        public string Ordering_Code { get; set; }
        public string Panel { get; set; }
        public string DI { get; set; }
        public string DO { get; set; }
        public string AI { get; set; }
        public string AO { get; set; }
        public string Ethernet { get; set; }
        public string ASI { get; set; }
    }
}

我尝试在网络上搜索,但是找不到一个好的解决方案。


请注意,这不是直接的解决方案,但相关的信息可以在以下链接中找到:https://dapper-tutorial.net/knowledge-base/38234218/dapper---map-result-set-with-unknown-number-of-columns-to-object-with-array-property - Soumen Mukherjee
可能的建议 https://stackoverflow.com/q/16944038/125981 - Mark Schultheiss
这可能正是你所寻找的内容,或者是https://dev59.com/MXA85IYBdhLWcg3wBO3h#2978440的第二部分。 - Mark Schultheiss
是的,就是这样,我现在甚至不需要进行转换了。我不知道你可以直接在bulkcopy.WriteToServer(DataTable)中使用DataTable。 - Dick Hof
1个回答

0

我把它改成了这样,现在它可以工作了。谢谢。

/// <summary>
/// Import Excel document into the SQL Database and Datagridview
/// </summary>
private void ImportExcel_Click(object sender, EventArgs e)
{
        try
        {
            using (OpenFileDialog ImportExcelFileDialog = new OpenFileDialog() { Filter = "Excel Workbook|*.xlsx|Excel 97 -2003 Workbook|*.xls" })
            {
                if (ImportExcelFileDialog.ShowDialog() == DialogResult.OK)
                {
                    using (var stream = File.Open(ImportExcelFileDialog.FileName, FileMode.Open, FileAccess.Read))
                    {
                        using (IExcelDataReader Reader = ExcelReaderFactory.CreateReader(stream))
                        {
                            DataSet result = Reader.AsDataSet(new ExcelDataSetConfiguration()
                            {
                                ConfigureDataTable = (_) => new ExcelDataTableConfiguration() { UseHeaderRow = true }
                            });
                            SqlConnection Connection = new SqlConnection(SQL_Commands._Connectionstring);
                            Connection.Open();
                            sqlcommands.DeleteTable(SqliteDatabase[3]);
                            //this is created from a SQL Query file there is only one column and that is ID
                            sqlcommands.RecreateDatabase(Connection);
                            //Get result from Excel file and create a Table from it.
                            tableCollection = result.Tables;
                            DataTable dt = tableCollection[SqliteDatabase[3]];

                           // Create new List
                            List<string> ListColums = new List<string>();

                            //Create columns in SQL Database 
                            foreach(DataColumn column in dt.Columns)
                            {
                                if(column.ColumnName != "ID")
                                {
                                    string columnName = "[" + column.ColumnName + "]";
                                    sqlcommands.AddColumn(columnName, SQLite.SqliteDatabase[3], "Text");
                                    //Add Column Names to List<string>
                                    ListColums.Add(column.ColumnName);
                                }
                            }

                            //write already the values to datagridview 
                            InstrumentsBindingSource.DataSource = dt;

                            //Create a connection
                            sqlcommands.ImportFromExcel(Connection,dt, ListColums);
                            sqlcommands.UpdateTableTotal(SQLite.SqliteDatabase[3], InstrumentsBindingSource, dataGridView1);
                        }
                    }
                }
            }
        }
        catch (Exception EX)
        {
            MessageBox.Show(EX.ToString(), "UpdateTableTotal", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
}

public void ImportFromExcel(SqlConnection connection,DataTable _dt,List<string> ColumnNames )
{
    try
    {
            // Get the DataTable 
            DataTable dtInsertRows = _dt;

            using (SqlBulkCopy bulkcopy = new SqlBulkCopy(connection.ConnectionString, SqlBulkCopyOptions.KeepIdentity))
            {
                bulkcopy.DestinationTableName = "Instruments";
                bulkcopy.BatchSize = _dt.Rows.Count;

                foreach (string Column in ColumnNames)
                {
                    var split = Column.Split(new[] { ',' });
                    bulkcopy.ColumnMappings.Add(split.First(), split.Last());
                }
                bulkcopy.WriteToServer(dtInsertRows);
            }
    }
    catch (Exception EX)
    {
        MessageBox.Show(EX.ToString(), "InsertBulk", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接