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

时间:2012-05-19 11:25:02

标签: c# .net sql arraylist sqldatareader

我有以下代码,它接受一个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可以存储任何东西。任何人都可以告诉我为什么这个演员阵容无法演出?

谢谢,

安迪

4 个答案:

答案 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方法。对于从方法返回,通用方法是优选的。同样,dynamicDataGridView无效。

最后,我注意到没有参数;你总是想使用参数而不是连接。 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?

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