如何将数据读取器数据分配到(T)的通用列表中 [英] How to assign datareader data into generic List ( of T )
问题描述
我想将datareader数据分配到通用List(of T)中。
我不想读取特定的列项名称。
示例代码:
共享函数FormatUserList(作为OracleDataReader的ByVal PoReader)作为List(用户)
Dim oUserList作为新列表(用户)()
Dim oUser作为用户
Dim dt作为新的DataTable
dt = PoReader.GetSchemaTable()
当PoReader.Read()
Dim index As Integer = 0
oUser =新用户()
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 =转换.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
返回oUserList
End Function
我需要类似下面的内容,但在将第二行数据循环到 SetValue
。
对象引用未设置为对象的实例。
Do虽然PoReader.Read()
oUserGroup =新的UserGroups()
Dim type As Type = GetType(UserGroups)
Dim obj As Object = Activator.CreateInstance(type)
对于每一行DataRow在dt.Rows
sColName = row.Field(Of String)(ColumnName)
type.GetProperty(sColName).SetValue(obj,PoReader(row.Field(Of String)(ColumnName)),Nothing)
oUserGroupLis t.Add(obj)
下一行
Loop
目前还不清楚 dt
在这里的作用;然而,下面的第二个例子显示了一个基本的基于反射的循环(使用C# - 你必须翻译)。
然而, ,在这之前,我真的认为你应该看看dapper / a>,它使得数据访问(包括参数化)如下简单:
string region =North;
var people = conn.Query< Person>(select * from People where Region = @ region,
new {region})。ToList();
(支持您想要的大多数常见数据场景,包括类型转换)以及比你可以动摇一个基于IL的棒子)
用反射的方式来做这件事很慢,例如:
static List< T>阅读< T>(IDataReader reader)
其中T:class,new()
{
List< T> results = new List< T>();
Type type = typeof(T);
if(reader.Read())
{
//至少一行:解析属性
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; //未映射
object val = reader.IsDBNull(i)? null:reader [i];
prop.SetValue(obj,val);
}
results.Add(obj);
} while(reader.Read());
}
返回结果;
}
I would like assign datareader data into generic List ( of T ).
I do not want to read the specific column item name. I want to make it dynamic.
Example code:
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
I need something like below, but I receive an error when looping the 2nd row data to SetValue
.
"Object reference not set to an instance of an object."
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
It is unclear what the role of dt
is here; however, a very basic reflection-based loop (using C# - you would have to translate) is shown in the second example below.
However, before doing that, I really think you should take a look at "dapper", which makes data access (including parameterization) as simple as:
string region = "North";
var people = conn.Query<Person>("select * from People where Region=@region",
new { region }).ToList();
(with support for most common data scenarios you would want, including type translation - and more insane optimization than you can shake an IL-based stick at)
And to do it the slow way with reflection, something like:
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;
}
这篇关于如何将数据读取器数据分配到(T)的通用列表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!