寻找有关以下问题的建议:访问数据和填充列表/数组列表/列表
我想做这样的事情:
- 使用数据读取器访问数据库中的记录。 我不知道会返回多少条记录 - 大多数时候在 1 到 300 条之间。 每条记录的数据将类似于“0023”、“Eric”、“Harvest Circle”、“Boston”。
- 我想立即填充一些内容(数组、列表?)并关闭连接。
- 将填充的对象传递回我的 Web 服务,在发送到客户端之前我会将其转换为 JSON。
我遇到的问题是用数据读取器中的数据填充哪些对象。 我开始使用 ArrayList(现在已经阅读了有关使用 List 的信息),但是尽管我可以取回所有记录(在本例中只有 2 个项目),但我无法访问每个项目内的各个字段(Eric、Boston、 ETC)。
输入 B 计划:对于 datareader 中的每条记录,将各个列值添加到数组中,然后将每个数组添加到列表中。 我认为这会起作用,但是当我不知道需要实例化多少个数组时,我不确定如何实例化数组。 换句话说,我通常会这样做 string[] myarray = new string[]{"eric", "boston", "etc"};
但如果我有多个记录,那会是什么样子? 填充数组,添加到列表,清除原始数组,然后重新填充它,将其添加到列表等?
任何帮助将不胜感激! 此外,我对其他方法持开放态度。
谢谢!
I am looking to do something like this:
- access records in db with a datareader. I won't know how many records will come back - somewhere between 1 and 300 most of the time. The data will look something like this "0023","Eric","Harvest Circle", "Boston" for each record.
- I wanted to immediately populate something (array, list?) and close the connection.
- Pass the filled object back to my webservice where I will convert it to JSON before sending on to client.
The problem I am running into is what object/objects to populate with data from the datareader. I started out using an ArrayList (and have now read about using List instead), but although I could get back all the records (in this case just 2 Items), I could not access the individual fields inside each Item (Eric, Boston, etc).
Enter Plan B: foreach record in datareader, add the individual column values to an array and then add each array to the List. I think this will work, but I am not sure how to instantiate an array when I don't know how many would need to be instantiated. In other words, I would normally do this string[] myarray = new string[]{"eric", "boston", "etc"};
But if I have multiple records, what does that look like? Populate array, add to List, clear original array and then repopulate it, add it to List, etc?
Any help would be greatly appreciated! Also, I am very open to alternative ways of doing this.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这里的标准答案是使用您需要的字段创建“实体”类,而不是使用像实体框架这样的持久层。 比如:
......然后将它们收集到某种集合中。
List
就可以了。如果您有大量的表或可变的字段列表,这可能会很难维护。 不过,对于简单的任务来说,这效果很好。
The standard answer here, short of using a persistence layer like the Entity Framework, is to create "entity" classes with the fields you need. Something like:
... and then collect these up in a collection of some kind. A
List<Customer>
is fine.If you have a large number of tables, or a mutable list of fields, this can get hard to maintain. For simple tasks, though, this works fine.
您可能不需要像
List
或数组这样的具体类。IEnumerable
可能就足够好了。 考虑到这一点,这是我最喜欢的模式:您还可以修改它来创建强类型业务对象,但我通常将其保留在单独的层中。 迭代器块将执行惰性计算/延迟执行,因此额外的转换层将不需要对结果进行额外的迭代。
这段代码有一个技巧。 您需要确保在某个时刻将每个记录中的数据复制到真实对象中。 您不能直接绑定到它,否则您可能会得到令人惊讶的结果。 我更经常使用的一种变体是使该方法变得通用,并需要一个 Func参数来在读取每条记录时对其进行翻译。
Odds are you don't need a concrete class like a
List
or array. AnIEnumerable
is probably good enough. With that in mind, this is my favorite pattern:You could also modify that to create strongly-typed business objects, but I generally keep that in a separate layer/tier. Iterator blocks will do lazy evaluation/deferred execution and so the extra translation tier will not require an additional iteration of the results.
There is one trick with this code. You need to be sure you copy the data in each record to a real object at some point. You can't bind directly to it, or you'll get potentially-surprising results. One variation I use more often is to make the method generic and require a
Func<IDataRecord, T>
argument to translate each record as it is read.迈克尔的答案通常是你最好的选择。 一旦事情开始变得复杂,您就可以添加抽象(您将需要接受 sql 读取器和各种其他有趣的东西的对象工厂)并开始传递对象和工厂。 我发现这个策略非常有用,并且编写良好的数据层类可以在整个数据库相关项目中使用。
一种替代方法是使用
SqlDataAdapter
并将输出转换为
DataSet
。 根据我的经验,这是非常笨拙的,而且通常是一个非常糟糕的主意。 也就是说,如果您倾向于获取一大块数据并对其进行操作(更新片段、添加新片段、删除片段),那么这可能是使用 C# 代码在内存中执行此操作的好方法。 在尝试这种技术之前请三思。 这基本上相当于获取数据并填充行列表,尽管 DataSet 中的内容比数组多一些(例如,它包括列名称)。我觉得使用
SqlDataAdapter
来填充DataSet
是为您提供问题中所要求的最接近的答案,但就为您提供您想要的内容而言,这是最糟糕的答案实际需要。Michael's answer is usually your best bet. Once things start getting complicated, you can add abstractions (you'll need object factories that take in sql readers and various other fun things) and start passing around objects and factories. I've found this strategy is pretty helpful, and a well-written datalayer class can be used throughout your database-related projects.
One alternative is to use an
SqlDataAdapter
and to convert your output to aDataSet
. In my experience this is pretty unwieldy and generally a pretty bad idea. That said, if your tendency is to grab a chunk of data, manipulate it (update pieces, add new pieces, delete pieces), this can be a nice way to do it in memory with C# code. Think twice before trying this technique. This is basically equivalent to grabbing data and populating a List of rows, though aDataSet
has a bit more stuff in it than an array (e.g. it includes column names).I feel like using an
SqlDataAdapter
to populate aDataSet
is the closest answer to giving you what you are asking for in your question but the worst answer in terms of giving you what you actually need.创建一个对象,该对象的属性与将在数据读取器中返回的字段相匹配:
然后,对数据读取器中的所有结果进行 foreach。 然后,创建此类型的对象,并使用该记录的列中的值设置所有属性。 然后,将它们添加到 List中。
Create an object that has properties that matches the fields that will be coming back in the datareader:
Then, foreach over all the results in the datareader. Then, create an object of this type and set all the properties with the values in the columns for that records. Then, add them to a List<MyClass>.
我建议您研究 LINQ to SQL(如果您有一个非常简单的数据库)或 NHibernate(如果您有一个更复杂的数据库)。 这些 OR 映射器可以极大地简化将 SQL 查询转换为可在您的域中使用、通过服务传递等的对象的过程。
I would recommend looking into LINQ to SQL (if you have a very simple database), or NHibernate (if you have a more complex database). These are OR mappers that can greatly simplify the process of turning a SQL query into objects that can be used in your domain, passed through services, etc.
我认为这里需要一个简单的解决方案。 我将创建一个 DataAdapter,然后用数据填充 DataTable。 然后您可以关闭连接,并且数据表将保持填充状态,因为与 ADO 不同,ADO.NET 默认为断开连接的记录集。
然后,您可以通过字段名轻松访问数据,例如,
如果您要做的只是将数据转换为 JSON,则创建一个将属性映射到数据库字段的对象似乎没有必要,因为 ADO.NET 为您提供了开箱即用的功能。
I think a simple solution is in order here. I would create a DataAdapter and then fill a DataTable with the data. You can then close the connection, and the data table will remain populated, since, unlike ADO, ADO.NET defaults to disconnected recordsets.
You can then easily access the data by fieldname, e.g.,
If all you are going to do is convert the data to JSON, creating an object that maps properties to the database fields seems unnecessary since ADO.NET gives you this out of the box.