【发布时间】:2011-03-02 22:48:50
【问题描述】:
我正在创建一个带有访问 SQLCE 数据库的方法的数据库助手类。我想使用相同的方法来使用包含与不同表中的字段匹配的属性的不同类来读取行。要使用的类是在运行时确定的,我想将一个包含类中对象的列表传递给方法,并获取属性名并使用它们来读取数据库。会非常方便,因为我可以将它用于我的所有 (SQLCE-) 数据库。
(我更新了错误代码以便在此处提供解决方案)
#region ReadData
///----------------------------------------------------------------------
/// <summary>
/// Reads datarows from database and adds them to list.
/// </summary>
/// <param name="data">List containing objects with properties.</param>
/// <param name="table">Table in database.</param>
/// <param name="search">Substring of SQL-statement that follows 'WHERE'.</param>
/// <param name="connect">Connectionstring.</param>
/// <returns>true if successfull</returns>
///----------------------------------------------------------------------
public static bool ReadData<T>(List<T> data, string table, string search, string connect) where T : class, new()
{
// Return if input id missing
if (data == null || table == "" || connect == "") return false;
// retrieve properties from Data
PropertyInfo[] propinf = typeof(T).GetProperties();
// Create string with SQL-statement
string fields = "";
// retrieve fields from propinf
foreach (PropertyInfo p in propinf)
{
fields += fields == "" ? p.Name : ", " + p.Name;
}
// create SQL SELECT statement with properties and search
string sql = "SELECT " + fields + " FROM " + table;
sql += search == "" ? "" : " WHERE " + search;
// Instantiate and open database
SqlCeConnection cn = new SqlCeConnection(connect);
if (cn.State == ConnectionState.Closed)
cn.Open();
data.Clear(); // just in case
try
{
SqlCeCommand cmd = new SqlCeCommand(sql, cn);
cmd.CommandType = CommandType.Text;
SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Scrollable);
if (rs.HasRows) // Only if database is not empty
{
while (rs.Read()) // read database
{
// instantiate single item of list Data
var dataitem = new T();
int ordinal = 0;
foreach (PropertyInfo p in propinf)
{
// read database and
PropertyInfo singlepropinf = typeof(T).GetProperty(p.Name);
ordinal = rs.GetOrdinal(p.Name);
singlepropinf.SetValue(dataitem, rs.GetValue(ordinal), null); // fill data item
}
data.Add(dataitem); // and add it to data.
}
}
else
{
MessageBox.Show("No records matching '" + search + "'!");
return false;
}
}
catch (SqlCeException sqlexception)
{
MessageBox.Show(sqlexception.Message, "SQL-error.", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error.", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
finally
{
cn.Close();
}
return true;
}
#endregion
我有两个问题:
1) 我如何传递这个未知类型的列表?到目前为止我找到的答案并没有帮助我解决这个问题。
2) 我如何实例化未知类型类的对象(在编译时)以便将其添加到列表中而不会导致编译错误?
非常感谢!
【问题讨论】:
-
不应该在 While(rs.Read()) 循环内移动 _dataItem 的创建吗?否则每次都会插入相同的 _dataItem。也许我错过了什么?问候莫滕
标签: c# list methods instantiation propertyinfo