用 SQL 语句的结果填充任何 ArrayList

本文关键字:填充 任何 ArrayList 结果 SQL 语句 | 更新日期: 2023-09-27 18:34:36

我有以下代码,它采用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 时出现错误:

无法将类型为"系统.对象"的对象强制转换为类型 "测试利用组织"。

我的印象是对象可以存储任何东西。谁能告诉我为什么不能表演这个演员?

谢谢

安 迪

用 SQL 语句的结果填充任何 ArrayList

除非你使用的是.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();

如果您使用的是 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<Organisations> list = new List<Organisations>();

http://msdn.microsoft.com/en-us/library/ms379564(v=vs.80(.aspx

如果使用与返回数据集中的列同名创建类的属性,则可以使用反射从数据读取器或数据表构造任何类型的对象(如果数据读取器或数据表的列与对象的属性匹配(。

您可以在此链接中看到以下内容。它演示如何将数据表转换为自定义类的集合。使用数据读取器将是相同的。

您不能也使用 DataContext 并提供您的连接字符串,然后使用 Linq 吗?

http://msdn.microsoft.com/en-us/library/bb399375.aspx