我有以下代码,它接受一个SQL语句(字符串),将结果加载到一个ArrayList(organisationList),这是一个组织的集合:
public void FillDataGridView(DataGridView grid, string SQLCommand)
{
SqlCommand dataCommand = new SqlCommand();
dataCommand.Connection = dataConnection;
dataCommand.CommandType = CommandType.Text;
dataCommand.CommandText = SQLCommand;
SqlDataReader dataReader = dataCommand.ExecuteReader();
while (dataReader.Read())
{
Organisation org = new Organisation();
org.OrganisationId = (int)dataReader["OrganisationId"];
org.OrganisationName = (string)dataReader["OrganisationName"];
organisationList.Add(org);
}
grid.DataSource = organisationList;
dataReader.Close();
}
我想调整此方法以填充传入其中的ArrayList。
我是否可以将列表传递给方法,并具有以下内容:
public void FillArrayList(DataGridView grid, SqlDataReader reader, ArrayList list)
{
//Fill the list with the contents of the reader
while (reader.Read())
{
Object obj = new Object
for(int i; i = 0; i < obj.NoOfProperties)
{
obj.Property[i] = reader[i];
}
list.Add(obj);
}
}
对不起,如果这有点模糊,我对OOP很新,有点迷失了!
编辑:根据Darren Davies的建议,我修改了方法如下:
public void FillArrayList<T>(DataGridView grid, SqlDataReader reader, List<T> list)
{
//Fill the list with the contents of the reader
while (reader.Read())
{
Object obj = new Object();
Type type = typeof(T);
FieldInfo[] fields = type.GetFields(); // Get the fields of the assembly
int i = 0;
foreach(var field in fields)
{
field.SetValue(obj, reader[i]); // set the fields of T to the reader's value
// field.setValue(obj, reader[field.Name]); // You can also set the field value to the explicit reader name, i.e. reader["YourProperty"]
i++;
}
list.Add((T)obj);
}
grid.DataSource = list;
}
当我运行代码时,在将对象转换为输入T:
时出现错误无法将类型为“System.Object”的对象强制转换为类型 'TestHarness.Organisation'。
我的印象是Object可以存储任何东西。任何人都可以告诉我为什么这个演员阵容无法演出?
谢谢,
安迪
答案 0 :(得分:5)
除非您使用的是.NET 1.1,否则您可能不应该使用ArrayList
;通用List<T>
更可取。
您无法将成员添加到object
- 它不可扩展。您需要知道要创建的对象的类型。泛型将是一个合理的对象。但是,为了节省您的时间,您可以查看dapper:
var list = dataConnection.Query<YourType>(SQLCommand).ToList();
使用直接列名到成员名称映射,将执行所有操作。您需要创建一个YourType
类,其中包含您期望的属性(适当类型)。
如果您使用的是4.0,则dapper也支持dynamic
:
var list = dataConnection.Query(SQLCommand).ToList();
这使用dynamic
,因此你仍然可以(不声明类型):
foreach(var obj in list) {
Console.WriteLine(obj.OrganisationId);
Console.WriteLine(obj.OrganisationName);
}
就个人而言,如果数据的使用距离非常接近,我只会使用dynamic
方法。对于从方法返回,通用方法是优选的。同样,dynamic
与DataGridView
无效。
最后,我注意到没有参数;你总是想使用参数而不是连接。 Dapper也支持:
string foo = ...;
var list = dataConnection.Query<YourType>(
"select * from SomeTable where Foo = @foo", new { foo }).ToList();
答案 1 :(得分:2)
如果您使用的是C#2.0。或更多使用Generics
而不是ArrayList
。
您可以使用Reflection
获取您传入的类型的属性:
public void FillArrayList<T>(DataGridView grid, SqlDataReader reader, List<T> list)
{
//Fill the list with the contents of the reader
while (reader.Read())
{
Object obj = new Object();
Type type = typeof(T); // get the type of T (The paramter you passed in, i.e. Organisations)
FieldInfo[] fields = type.GetFields(); // Get the fields of the assembly
int i = 0;
foreach(var field in fields) // Loop round the fields
{
field.setValue(obj, reader[i]); // set the fields of T to the readers value
// field.setValue(obj, reader[field.Name]); // You can also set the field value to the explicit reader name, i.e. reader["YourProperty"]
i++;
}
list.Add(obj);
}
}
要调用它:
FillArrayList(grid, reader, list);
其中list是List类型的Organizations
List<Organisations> list = new List<Organisations>();
http://msdn.microsoft.com/en-us/library/ms379564(v=vs.80).aspx
答案 2 :(得分:1)
如果您创建的类的属性与返回的数据集中的列具有相同的名称,那么您可以使用反射从数据读取器或数据表构建任何类型的对象(如果数据读取器的列或数据表和属性对象的匹配)。
您可以看到以下this链接。它显示了如何将数据表转换为自定义类的集合。使用数据阅读器是一样的。
答案 3 :(得分:0)
您是否也可以使用DataContext并提供连接字符串然后使用Linq?