3

我有以下代码,它采用 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

4 回答 4

6

除非您使用的是 .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();
于 2012-05-19T11:40:09.063 回答
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

于 2012-05-19T11:47:40.530 回答
1

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

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

于 2012-05-19T11:29:48.033 回答
0

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

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

于 2012-05-19T12:07:54.477 回答