gpt4 book ai didi

c# - 如何将 DataReader 映射到类属性并保持性能?

转载 作者:太空狗 更新时间:2023-10-29 20:25:29 24 4
gpt4 key购买 nike

前言:

  1. 所有数据连接字符串,连接等是使用创建的DbProviderFactories。
  2. 代码混合了 C# 和 VB.Net 来自多个库。

我正在将 DbDataReader 映射到实体并有一些基准:

[0] retrieved 159180 records in 45135 ms
[1] retrieved 159180 records in 45008 ms
[2] retrieved 159180 records in 44814 ms
[3] retrieved 159180 records in 44987 ms
[4] retrieved 159180 records in 44914 ms
[5] retrieved 159180 records in 45224 ms
[6] retrieved 159180 records in 45829 ms
[7] retrieved 159180 records in 60762 ms
[8] retrieved 159180 records in 52128 ms
[9] retrieved 159180 records in 47982 ms

考虑到从 Sql Server Management Studio 查询只需要 17 秒,这是一个很长的时间并且非常糟糕。我的选择语句:

“从 tbl_MyTable 中选择 *”

表包含 43 个字段,可能没有按应有的方式索引;但是,执行全选,我不认为索引会出现问题。所以……这就是我正在做的:

定义一个实体:

public class Concept
{
#region Columns
[DataParameter("ConceptID", DbType.Int32)]
public Int32 ConceptID
{ get; set; }
[DataParameter("ConceptName", DbType.String)]
public string ConceptName
{ get; set; }
[DataParameter("ConceptTypeID", DbType.Int32)]
public Int32 ConceptTypeID
{ get; set; }
[DataParameter("ActiveYN", DbType.Boolean)]
public bool ActiveYN
{ get; set; }
#endregion
}

查询DataReader:

for (int i = 0; i <= 99; i++)
{
sw.Start();
var results = session.QueryReader<Concept>(
new SqlCommand(command), dr => new Concept());

sw.Stop();

Console.WriteLine("[{0}] retrieved {1} records in {2} ms", i, results.Count(), sw.ElapsedMilliseconds);
sw.Reset();
}

...调用:

Public Function QueryReader(Of TEntity As {Class, New})(ByVal Command As DbCommand, _
ByVal Projection As Func(Of DbDataReader, TEntity)) _
As IEnumerable(Of TEntity)

Dim list As IEnumerable(Of TEntity)

Command.Connection = dataReader.NewConnection
Command.Connection.Open()

Using _reader As DbDataReader = Command.ExecuteReader()
list = _reader.Query(Of TEntity)(Projection).ToList()
End Using

Command.Connection.Close()

Return list
End Function

...和扩展方法QueryReader<T> : 编辑新 TEntity() 的位置 - 感谢@Henk

public static IEnumerable<TEntity> Query<TEntity>(this DbDataReader Reader,
Func<DbDataReader, TEntity> Projection)
where TEntity : class, new()
{
// moving this reflection to another class
Dictionary<string, PropertyInfo> props;

while (Reader.Read())
{
TEntity entity = new TEntity();

if (!entities.TryGetValue(typeof(TEntity).ToString(), out props))
{
// reflection over TEntity
props = (from p in entity.GetType().GetProperties()
from a in p.GetCustomAttributes(typeof(DataParameterAttribute), false)
select p)
.ToDictionary(p => p.Name);

entities.Add(typeof(TEntity).ToString(), props);
}

foreach (KeyValuePair<string, PropertyInfo> field in props)
{
if (null != Reader[field.Key] && Reader[field.Key] != DBNull.Value)
{ field.Value.SetValue(entity, Reader[field.Key], null); }
}

yield return entity;
}
}

任何关于提高性能的建议都将不胜感激......


更新

我按照@EtienneT 的建议实现了 dapper-dot-net - 这是检索时间:

[0] retrieved 159180 records in 6874 ms
[1] retrieved 159180 records in 6866 ms
[2] retrieved 159180 records in 6570 ms
[3] retrieved 159180 records in 6785 ms
[4] retrieved 159180 records in 6693 ms
[5] retrieved 159180 records in 6735 ms
[6] retrieved 159180 records in 6627 ms
[7] retrieved 159180 records in 6739 ms
[8] retrieved 159180 records in 6569 ms
[9] retrieved 159180 records in 6666 ms

最佳答案

您是否考虑过像 dapper.net 这样的微型 ORM?

https://github.com/StackExchange/dapper-dot-net

它由 StackOverflow 的开发人员制作,将 SQL 查询直接映射到您的对象。它生成并缓存 IL 代码以将 SQL 结果映射到您的对象。因此,每种类型的 IL 代码只生成一次。从未使用过它,但如果您需要将 SQL 结果映射到 .net 对象的性能,那么它就是您需要的库。

关于c# - 如何将 DataReader 映射到类属性并保持性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6142659/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com