如何轻松地将 DataReader 转换为 List?
我在 DataReader
中有数据,我想将其转换为 List
。 对此有什么可能的简单解决方案?
例如,在 CustomerEntity 类中,我有 CustomerId 和 CustomerName 属性。如果我的 DataReader 将这两列作为数据返回,那么如何将其转换为 List
。
I have data in a DataReader
which I want to be converted to a List<T>
.
What is a possible simple solution for this?
For e.g. in CustomerEntity class, I have CustomerId and CustomerName properties.If my DataReader returns these two columns as data, then how can I convert it into List<CustomerEntity>
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
我建议为此编写一个扩展方法:
如果需要,您可以使用 LINQ 的
ToList()
方法将其转换为List
,如下所示:实际上会建议将
FromDataReader
方法放入Customer
(或其他地方):这样会留下:(
我认为类型推断不起作用在这种情况下,但我可能是错的......)
I would suggest writing an extension method for this:
You can then use LINQ's
ToList()
method to convert that into aList<T>
if you want, like this:I would actually suggest putting a
FromDataReader
method inCustomer
(or somewhere else):That would leave:
(I don't think type inference would work in this case, but I could be wrong...)
我用这个案例写了下面的方法。
首先,添加命名空间:
System.Reflection
例如:
T
是返回类型(ClassName),dr
是映射DataReader 的参数
C#,调用映射方法如下:
这是映射方法:
VB.NET,调用映射方法如下:
这是映射方法:
I have written the following method using this case.
First, add the namespace:
System.Reflection
For Example:
T
is return type(ClassName) anddr
is parameter to mappingDataReader
C#, Call mapping method like the following:
This is the mapping method:
VB.NET, Call mapping method like the following:
This is the mapping method:
我见过使用反射和属性或字段上的属性将 DataReader 映射到对象的系统。 (有点像 LinqToSql 所做的。)它们节省了一些输入,并且可以减少 DBNull 等编码时的错误数量。一旦缓存生成的代码,它们也可以比大多数手写代码更快,所以 如果您经常这样做,请考虑“高路”。
请参阅“A Defense of .NET 中的反射” 就是这样的一个例子。
然后,您可以编写如下代码
...
(AutoMap(),是一种扩展方法)
@Stilgar,感谢您的伟大评论
如果能够,您很可能会最好使用 NHibernate、EF 或 Linq to Sql 等在旧项目上(或出于其他(有时是有效的)原因,例如“不是在这里发明的”、“对存储过程的热爱”等)并不总是可以使用 ORM,因此轻量级系统对于拥有“ 如果您也需要
编写大量 IDataReader 循环,您将看到减少编码(和错误)的好处,而无需更改您正在使用的系统的体系结构。这并不是说这是一个很好的架构。
我假设 CustomerDTO 不会脱离数据访问层,并且复合对象等将由数据访问层使用 DTO 对象构建。
在我写下这个答案几年后,Dapper 进入了 .NET 的世界,它很可能是编写 onw AutoMapper 的一个非常好的起点,也许它将完全消除您这样做的需要。
I have seen systems that use Reflection and attributes on Properties or fields to maps DataReaders to objects. (A bit like what LinqToSql does.) They save a bit of typing and may reduce the number of errors when coding for DBNull etc. Once you cache the generated code they can be faster then most hand written code as well, so do consider the “high road” if you are doing this a lot.
See "A Defense of Reflection in .NET" for one example of this.
You can then write code like
...
(AutoMap(), is an extension method)
@Stilgar, thanks for a great comment
If are able to you are likely to be better of using NHibernate, EF or Linq to Sql, etc However on old project (or for other (sometimes valid) reasons, e.g. “not invented here”, “love of stored procs” etc) It is not always possible to use a ORM, so a lighter weight system can be useful to have “up your sleeves”
If you every needed too write lots of IDataReader loops, you will see the benefit of reducing the coding (and errors) without having to change the architecture of the system you are working on. That is not to say it’s a good architecture to start with..
I am assuming that CustomerDTO will not get out of the data access layer and composite objects etc will be built up by the data access layer using the DTO objects.
A few years after I wrote this answer Dapper entered the world of .NET, it is likely to be a very good starting point for writing your onw AutoMapper, maybe it will completely remove the need for you to do so.
最简单的解决方案:
The simplest Solution :
我会(并且已经)开始使用 Dapper。使用您的示例就像(从内存中编写):
CreateConnection()
将处理访问您的数据库并返回连接。Dapper 自动处理数据字段到属性的映射。它还支持多种类型和结果集,并且速度非常快。
查询返回
IEnumerable
,因此返回ToList()
。I would (and have) started to use Dapper. To use your example would be like (written from memory):
CreateConnection()
would handle accessing your db and returning a connection.Dapper handles mapping datafields to properties automatically. It also supports multiple types and result sets and is very fast.
Query returns
IEnumerable
hence theToList()
.显然 @Ian Ringrose 的中心论点是你应该为此使用一个库,这是这里最好的单一答案(因此+1),但对于最少的一次性或演示代码,这里有一个具体的说明 < code>@SLaks 对
@Jon Skeet
更详细(+1)的答案的微妙评论:如
@Jon Skeet
的答案,该位可以提取到帮助程序中(我喜欢将它们转储到查询类中):
并用作:
更新 Mar 9 13:另请参阅 一些优秀的进一步微妙的编码技术可以在这个答案中拆分出样板
Obviously
@Ian Ringrose
's central thesis that you should be using a library for this is the best single answer here (hence a +1), but for minimal throwaway or demo code here's a concrete illustration of@SLaks
's subtle comment on@Jon Skeet
's more granular (+1'd) answer:As in
@Jon Skeet
's answer, thebit can be extracted into a helper (I like to dump them in the query class):
and used as:
UPDATE Mar 9 13: See also Some excellent further subtle coding techniques to split out the boilerplate in this answer
您不能简单地(直接)将数据读取器转换为列表。
您必须循环遍历 datareader 中的所有元素并将其插入到
示例代码下方的列表中
You cant simply (directly) convert the datareader to list.
You have to loop through all the elements in datareader and insert into list
below the sample code
我已经在一个宠物项目中介绍了这个..
使用你想要的。
请注意,ListEx 实现了 IDataReader 接口。
或者使用对象映射,如下例所示。
看看 http://caprisoft.codeplex.com
I've covered this in a pet project..
use what you want.
Note that the ListEx implements the IDataReader interface.
Or use object mapping like in the following example.
Have a look at http://caprisoft.codeplex.com
我知道这个问题很旧,并且已经回答了,但是...
既然 SqlDataReader 已经实现了 IEnumerable,为什么需要在记录上创建循环?
我一直在使用下面的方法,没有任何问题,也没有任何性能问题:到目前为止,我已经使用 IList、List(Of T)、IEnumerable、IEnumerable(Of T)、IQueryable 和 IQueryable(Of T)
强类型 进行了测试类的
用法
I know this question is old, and already answered, but...
Since SqlDataReader already implements IEnumerable, why is there a need to create a loop over the records?
I've been using the method below without any issues, nor without any performance issues: So far I have tested with IList, List(Of T), IEnumerable, IEnumerable(Of T), IQueryable, and IQueryable(Of T)
Strong Typing Class
Usage