如何将datareader数据分配到通用列表(T)

时间:2013-10-11 08:09:46

标签: vb.net list generics

我想将datareader数据分配到通用List(of T)。

我不想读取特定的列项名称。我想让它充满活力。

示例代码:

Shared Function FormatUserList(ByVal PoReader As OracleDataReader) As List(Of Users)
    Dim oUserList As New List(Of Users)()
    Dim oUser As Users
    Dim dt As New DataTable
    dt = PoReader.GetSchemaTable()

    Do While PoReader.Read()
        Dim index As Integer = 0
        oUser = New Users()

        oUser.LoginId = Convert.ToString(PoReader("LoginId"))
        oUser.Password = Convert.ToString(PoReader("Password"))
        oUser.FirstName = Convert.ToString(PoReader("FirstName"))
        oUser.LastName = Convert.ToString(PoReader("LastName"))
        oUser.NRIC = Convert.ToString(PoReader("NRIC"))
        oUser.MobileNo = Convert.ToInt64(PoReader("MobileNo"))
        oUser.Address = Convert.ToString(PoReader("Address"))
        oUser.Zip = Convert.ToInt64(PoReader("Zip"))
        oUser.State = Convert.ToInt64(PoReader("state"))
        oUser.UserGroupId = Convert.ToInt64(PoReader("UserGroupId"))
        oUser.CompanyId = Convert.ToInt64(PoReader("CompanyId"))
        oUser.Active = Convert.ToInt64(PoReader("Active"))
        oUserList.Add(oUser)
    Loop

    Return oUserList
End Function

我需要类似下面的内容,但在将第二行数据循环到SetValue时收到错误。

“对象引用未设置为对象的实例。”

Do While PoReader.Read()

  oUserGroup = New UserGroups()

  Dim type As Type = GetType(UserGroups) 
  Dim obj As Object = Activator.CreateInstance(type)

    For Each row As DataRow In dt.Rows
        sColName = row.Field(Of String)("ColumnName")
        type.GetProperty(sColName).SetValue(obj, PoReader(row.Field(Of String)("ColumnName")), Nothing)
        oUserGroupList.Add(obj)
    Next row
Loop

1 个答案:

答案 0 :(得分:0)

目前还不清楚dt的作用是什么;但是,非常基本的基于反射的循环(使用C# - 您必须翻译)将在下面的第二个示例中显示。

但是,在此之前,我确实认为你应该看看"dapper",它使数据访问(包括参数化)简单如下:

string region = "North";
var people = conn.Query<Person>("select * from People where Region=@region",
           new { region }).ToList();

(支持你想要的大多数常见数据场景,包括类型转换 - 以及比你可以撼动基于IL的棒更疯狂的优化)

用反射来缓慢进行,例如:

static List<T> Read<T>(IDataReader reader)
    where T : class, new()
{
    List<T> results = new List<T>();
    Type type = typeof(T);

    if (reader.Read())
    {
        // at least one row: resolve the properties
        PropertyInfo[] props = new PropertyInfo[reader.FieldCount];
        for (int i = 0; i < props.Length; i++)
        {
            var prop = type.GetProperty(reader.GetName(i),
                BindingFlags.Instance | BindingFlags.Public);
            if(prop != null && prop.CanWrite) props[i] = prop;
        }

        do
        {
            var obj = new T();
            for (int i = 0; i < props.Length; i++)
            {
                var prop = props[i];
                if (prop == null) continue; // not mapped

                object val = reader.IsDBNull(i) ? null : reader[i];
                prop.SetValue(obj, val);
            }
            results.Add(obj);
        } while (reader.Read());
    }
    return results;
}