Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以使用DataAdapter C填写列表吗_C#_Ado.net - Fatal编程技术网

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);
}