我希望做这样的事情:
我遇到的问题是用datareader填充数据的对象/对象。我开始使用ArrayList(现在已经阅读了有关使用List的内容),但是虽然我可以取回所有记录(在这种情况下只有2个项目),但我无法访问每个项目中的各个字段(Eric,Boston,等)。
在datareader中输入Plan B:foreach记录,将各列值添加到数组中,然后将每个数组添加到List中。我认为这会有效,但我不知道如何在不知道需要实例化多少数组的情况下实例化数组。换句话说,我通常会做这个字符串[] myarray = new string [] {“eric”,“boston”,“etc”};
但如果我有多条记录,那会是什么样子?填充数组,添加到List,清除原始数组然后重新填充它,将它添加到List等?
任何帮助将不胜感激!此外,我对采取其他方式非常开放。
谢谢!
答案 0 :(得分:5)
此处的标准答案是,使用像实体框架这样的持久层,不如使用您需要的字段创建“实体”类。类似的东西:
class Customer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
...然后将它们收集到某种类型的集合中。 List<Customer>
很好。
List<Customer> customers = new List<Customer>();
string connectionString = null;
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand("GetData");
using (IDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Customer c = new Customer();
c.Id = (int)reader["ID"];
c.FirstName = (string)reader["FirstName"];
c.LastName = (string)reader["LastName"];
customers.Add(c);
}
}
}
如果您有大量表或可变字段列表,则可能难以维护。但是,对于简单的任务,这很好。
答案 1 :(得分:3)
你可能不需要像List
或数组这样的具体类。 IEnumerable
可能已经足够好了。考虑到这一点,这是我最喜欢的模式:
public IEnumerable<IDataRecord> GetData()
{
using (var cn = getOpenConnection(connectionString))
using (var cmd = new SqlCommand("GetData", cn))
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return (IDataRecord)rdr;
}
}
}
您也可以修改它以创建强类型业务对象,但我通常将其保留在单独的层/层中。迭代器块将执行延迟评估/延迟执行,因此额外的转换层不需要额外的结果迭代。
此代码有一个技巧。您需要确保在某个时刻将每个记录中的数据复制到真实对象。您不能直接绑定它,否则您将获得可能令人惊讶的结果。我经常使用的一个变体是使方法通用,并且需要Func<IDataRecord, T>
参数来翻译每个记录。
答案 2 :(得分:1)
另一种方法是使用SqlDataAdapter
并将输出转换为DataSet
。根据我的经验,这是非常笨拙的,通常是一个非常糟糕的主意。也就是说,如果你倾向于抓取一大块数据,操纵它(更新碎片,添加新碎片,删除碎片),这可能是用C#代码在内存中完成它的好方法。在尝试这种技术之前要三思。这基本上等同于抓取数据并填充行列表,尽管DataSet
中的内容比数组多一些(例如它包含列名)。
我觉得使用SqlDataAdapter
来填充DataSet
是最接近的答案,可以在您的问题中提供您所要求的内容,但却是为您提供实际需要的最差答案。
答案 3 :(得分:0)
创建一个对象,该对象的属性与将在datareader中返回的字段相匹配:
public class MyClass
{
public int Id{get;set;}
public string Name{get;set;}
....
}
然后,预测datareader中的所有结果。然后,创建此类型的对象,并使用该记录的列中的值设置所有属性。然后,将它们添加到List&lt; MyClass&gt;。
答案 4 :(得分:0)
我建议查看LINQ to SQL(如果你有一个非常简单的数据库),或NHibernate(如果你有一个更复杂的数据库)。这些是OR映射器,可以大大简化将SQL查询转换为可在您的域中使用,通过服务传递等的对象的过程。
答案 5 :(得分:0)
我认为这里有一个简单的解决方案。我将创建一个DataAdapter,然后用数据填充DataTable。然后,您可以关闭连接,并且数据表将保持填充状态,因为与ADO不同,ADO.NET默认为断开连接的记录集。
然后,您可以通过fieldname轻松访问数据,例如
myDataTable["FirstName"].ToString()
如果要做的就是将数据转换为JSON,那么创建一个将属性映射到数据库字段的对象似乎是不必要的,因为ADO.NET为您提供了开箱即用的功能。