推广SQL插入字符串

时间:2014-11-10 03:45:24

标签: c# sql linq generalization

我必须在不使用存储过程的情况下执行大量SQL插入。

对于大类,插入字符串变得很大,所以我考虑构建一个通用的插入函数来处理它在传入一个对象时。我在下面写的内容有效,但它并不理想,因为(1)我必须指定所有可能的数据类型,(2)我必须将所有值转换回字符串以构建插入字符串,我宁愿使用参数值。

我只想要一个函数,我将它传递给一个对象类,函数将对象的值插入到数据库中(假设表中的所有列名都与对象的属性名匹配)

非常感谢任何想法,谢谢。

public static IEnumerable<KeyValuePair<string, T>> PropertiesOfType<T>(object obj)
{
    return from p in obj.GetType().GetProperties()
           where p.PropertyType == typeof(T)
           select new KeyValuePair<string, T>(p.Name, (T)p.GetValue(obj, null));
}

public string InsertString(string _table, object _class)
{
    Dictionary<string, string> returnDict = new Dictionary<string, string>();
    StringBuilder sb = new StringBuilder();
    foreach (var property in PropertiesOfType<DateTime>(_class))
        returnDict.Add(property.Key, property.Value.ToString("yyyy-MM-dd HH:mm:ss"));
    foreach (var property in PropertiesOfType<string>(_class))
        returnDict.Add(property.Key, property.Value);
    foreach (var property in PropertiesOfType<int>(_class))
    {
        if (property.Key == "Key")
            continue;
        returnDict.Add(property.Key, property.Value.ToString());
    }            
    foreach (var property in PropertiesOfType<bool>(_class))
    {
        if (property.Value)
            returnDict.Add(property.Key, "1");
        else
            returnDict.Add(property.Key, "0");
    }
    foreach (var property in PropertiesOfType<decimal>(_class))
        returnDict.Add(property.Key, property.Value.ToString());
    foreach (var property in PropertiesOfType<long>(_class))
        returnDict.Add(property.Key, property.Value.ToString());
    if (returnDict.Count == 1)
    {
        sb.Append(string.Format("INSERT INTO [{0}] ({1}) VALUES ('{2}')", _table, returnDict.ElementAt(0).Key, returnDict.ElementAt(0).Value));
    }
    else
    {
        for (int i = 0; i < returnDict.Count; i++)
        {
            if (i == 0)
                sb.Append(string.Format("INSERT INTO [{0}] ({1}, ", _table, returnDict.ElementAt(i).Key));
            else if (i == returnDict.Count - 1)
                sb.Append(string.Format("{0}) ", returnDict.ElementAt(i).Key));
            else
                sb.Append(string.Format("{0}, ", returnDict.ElementAt(i).Key));
        }
        for (int i = 0; i < returnDict.Count; i++)
        {
            if (i == 0)
                sb.Append(string.Format("VALUES ('{0}', ", returnDict.ElementAt(i).Value));
            else if (i == returnDict.Count - 1)
                sb.Append(string.Format("'{0}')", returnDict.ElementAt(i).Value));
            else
                sb.Append(string.Format("'{0}', ", returnDict.ElementAt(i).Value));
        }
    }        
    return sb.ToString();
}



string query = InsertString(_table, _obj);

1 个答案:

答案 0 :(得分:1)

我已经设法找到一种方法来做到这一点,我很高兴非常高兴,不需要任何外部库或框架。

基于@ HardikParmar的建议我构建了一个将类对象转换为数据表的新过程,然后将所有相关的数据类型存储为列。

然后使用类对象在结构化数据表中添加一行。

现在你有一行数据表有一行值。

然后我创建一个PARAMATERIZED插入语句。然后在我的命令文本中,我将值添加到参数中。

几乎干净,总是有改进的余地。

//this function creates the datatable from a specified class type, you may exclude properties such as primary keys
public DataTable ClassToDataTable<T>(List<string> _excludeList = null)
{
    Type classType = typeof(T);
    List<PropertyInfo> propertyList = classType.GetProperties().ToList();

    DataTable result = new DataTable(classType.Name);

    foreach (PropertyInfo prop in propertyList)
    {
        if (_excludeList != null)
        {
            bool toContinue = false;
            foreach (string excludeName in _excludeList)
            {
                if (excludeName == prop.Name)
                {
                    toContinue = true;
                    break;
                }
            }
            if (toContinue)
                continue;
        }
        result.Columns.Add(prop.Name, prop.PropertyType);
    }
    return result;
}
//add data to the table
public void AddRow(ref DataTable table, object data)
{
    Type classType = data.GetType();
    string className = classType.Name;

    if (!table.TableName.Equals(className))
    {
        throw new Exception("DataTableConverter.AddRow: " +
                            "TableName not equal to className.");
    }
    DataRow row = table.NewRow();
    List<PropertyInfo> propertyList = classType.GetProperties().ToList();
    foreach (PropertyInfo prop in propertyList)
    {            
        foreach (DataColumn col in table.Columns)
        {
            if (col.ColumnName == prop.Name)
            {
                if (table.Columns[prop.Name] == null)
                {
                    throw new Exception("DataTableConverter.AddRow: " +
                                        "Column name does not exist: " + prop.Name);
                }
                row[prop.Name] = prop.GetValue(data, null);
            }
        }                        
    }
    table.Rows.Add(row);
}
//creates the insert string
public string MakeInsertParamString(string _tableName, DataTable _dt, string _condition=null)
{
    StringBuilder sb = new StringBuilder();
    sb.Append(string.Format("INSERT INTO [{0}] (", _tableName));
    for (int i = 0; i < _dt.Columns.Count; i++)
    {
        sb.Append(string.Format("{0}", _dt.Columns[i].ColumnName));
        if (i < _dt.Columns.Count - 1)
            sb.Append(", ");                
    }
    sb.Append(") VALUES (");
    for (int i = 0; i < _dt.Columns.Count; i++)
    {
        sb.Append(string.Format("@{0}", _dt.Columns[i].ColumnName));
        if (i < _dt.Columns.Count - 1)
            sb.Append(", ");
    }
    sb.Append(")");
    if (!string.IsNullOrEmpty(_condition))
        sb.Append(" WHERE " + _condition);
    return sb.ToString();
}
//inserts into the database
public string InsertUsingDataRow(string _tableName, DataTable _dt, string _condition = null)
{
    try
    {
        using (SQLiteConnection conn = new SQLiteConnection(_dbPath))
        {
            string query = MakeInsertParamString(_tableName, _dt, _condition);
            SQLiteCommand cmd = new SQLiteCommand(query, conn);
            foreach (DataColumn col in _dt.Columns)
            {
                var objectValue = _dt.Rows[0][col.ColumnName];                    
                cmd.Parameters.AddWithValue("@" + col.ColumnName, objectValue);
            }
            conn.Open();
            cmd.ExecuteNonQuery();
            conn.Close();                
        }
        //return MakeInsertParamString(_tableName, _dt, _condition);
        return "Success";
    }
    catch (Exception ex) { return ex.Message; }
}