C# 我可以使用DataAdapter C填写列表吗
假设我有这个伪代码C# 我可以使用DataAdapter C填写列表吗,c#,ado.net,C#,Ado.net,假设我有这个伪代码 class SomeClass { class Person { public static string Name { get; set; } public static int Age { get; set; } } List<Person> person = new List<person>; public void SelectPerson() { DataTable
class SomeClass
{
class Person
{
public static string Name { get; set; }
public static int Age { get; set; }
}
List<Person> person = new List<person>;
public void SelectPerson()
{
DataTable dt = new DataTable();
SqlConnection conn = GetConnection();
conn.Open();
SqlDataAdapter da = new SqlDataAdapter("SELECT name, age FROM person", conn);
da.Fill(dt);
}
}
我可以根据DataAdapter的结果填写人员列表吗?
我该怎么做?或者有解决办法吗?谢谢…是的,你可以。遍历dt.行中的项目并手动将其转换为Person对象。首先,您需要使名称和年龄字段非静态,以便类的每个实例都有自己的这些属性值 然后你可以这样做:
foreach(DataRow row in dt.Rows){
Person p = new Person(){
Name = Convert.ToString(row["name"]),
Age = Convert.ToInt32(row["age"])
}
person.Add(p);
}
希望这有帮助 最好的方法可能是不要先读入数据表:
var dr = new DataReader(....) // Fill in what is needed, can't remember offhand
while(dr.Next())
{
persons.Add(
new Person() {
Name = (string) r["Name"],
Age = (int) r["Age"]
}
);
}
警告:如果要快速关闭DataReader/连接,请不要进行大量处理。上述代码比使用DataTable作为中介更有效
但如果您确实想首先使用数据表,则可以使用LINQ:
var list = dt.AsEnumerable().Select(r => new Person() {
Name = (string) r["Name"],
Age = (int) r["Age"] }
).ToList()
或者只需删除一行dt.Rows并创建一个新的person并将其添加到列表中
你也应该在你的周围使用。你也可以用它来做一些类似的事情
var list = (from tr in dt.AsEnumerable()
select new Person() {
Name = tr.Field<string>("Name"),
Age = tr.Field<int>("Age")
}).ToList();
Robert抢先回答了我的问题,只是使用了稍微不同的语法。除了提供的其他选项外,您还可以将执行推迟到需要时进行,并获得收益:
public static IEnumerable<Person> GetPeople()
{
using( var conn = GetConnection() )
{
conn.Open();
string sql = "SELECT name, age FROM person";
var cmd = new SqlCommand( sql, conn );
using( SqlDataReader rdr = cmd.ExecuteReader() )
{
if( rdr == null )
{
throw new NullReferenceException( "No People Available." );
}
while( rdr.Read() )
{
var person = new Person();
person.Name = rdr["name"].ToString();
person.Age = Convert.ToInt32 ( rdr["age"] );
yield return person;
}
}
}
}
一位用户最近问我一个关于在.NET2.0中将数据表转换为列表的问题。下面是执行此操作的代码: C
这是潜在的危险,因为当调用代码进行迭代时,连接保持打开状态。另外,如果调用方没有到达集合的末尾,会发生什么情况?连接被处理了吗?我想大多数代码都有潜在的危险。你的观点是可以理解的,应该加以考虑。关于这一点,这里有一个很好的解读,可能更好,我不熟悉Linq to数据集,因为我像瘟疫一样避免它们。@罗伯特·瓦格纳:我也是,但我们时不时地要处理遗留代码。这是真的,但谢天谢地,我还没有对C 3.0和datasetsPwninstein的交集提出一个有趣的观点。为什么人名和年龄是静态的?虽然linq版本不起作用。。。没有dt.Rows.Select作为数据表orry,使用dt.AsEnumerable,我对dr.Row集合不太熟悉。Post已修复,除了真正处理空值或无法将“System.DBNull”类型的对象强制转换为“System.String”类型之外,其他都可以->但我意识到这不适合您处理错误,因为答案是:DataReader不是性能的好解决方案。可能需要从DataTable/DataRow继承一些内容better@Hamid你能澄清这些问题吗?什么是更有效的解决方案?IIRC大多数使用ADO.NET读取数据的解决方案将使用数据读取器,包括填充数据表。我能想到的唯一一件事是,您不想让datareader保持太长时间的打开状态,这是通过一个紧密的循环来实现的。在大多数情况下,DB读取性能不是一个大问题。
// Assuming there is a DataTable called dt
List<DataRow> drlist = new List<DataRow>();
foreach (DataRow row in dt.Rows)
{
drlist.Add((DataRow)row);
}