通用SQL插入字符串
本文关键字:字符串 插入 SQL 通用 | 更新日期: 2023-09-27 18:29:59
我必须在不使用存储过程的情况下进行大量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);
我已经设法找到了一种不需要任何外部库或框架的方法,我对此感到非常满意。
根据@Hardikarmar的建议,我构建了一个将类对象转换为数据表的新过程,然后将所有相关的数据类型存储为列。
然后使用类对象将一行添加到结构化数据表中。
现在,您有一个数据表,其中有一行值。
然后我创建一个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; }
}