Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.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# 如何将DataReader映射到类属性并保持性能?_C#_Reflection_Datareader - Fatal编程技术网

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

C# 如何将DataReader映射到类属性并保持性能?,c#,reflection,datareader,C#,Reflection,Datareader,序言: 所有数据连接字符串, 使用创建连接等 DBProviderFactorys。 代码由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

序言:

所有数据连接字符串, 使用创建连接等 DBProviderFactorys。 代码由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  
考虑到从SQLServerManagementStudio进行查询只需17秒,这是一个相当长的时间,而且非常糟糕。我的选择声明:

从tbl_MyTable中选择*

该表包含43个字段,可能并没有像它应该的那个样最好地编制索引;然而,执行全选时,我并不认为索引会有问题。所以以下是我正在做的:

定义实体:

查询数据读取器:

。。。和扩展方法QueryReader:编辑新TEntity的位置-谢谢@Henk


你考虑过像dapper.net这样的微型ORM吗


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

160K条记录,其中43个字段通过反射填充实体?我会说45-50秒是相当不错的,但也许我太宽容了。@Anthony:我觉得这很不错。。。但我想要哇-尤其是因为我使用字典将读者[字段]映射到属性信息。。。但也许我的期望太高了;只是为了好玩,试着写一个老式的whileReader.Read循环,FX2.0风格。它会让你知道所有这些思考和间接的代价有多大。混合你的饮料?c和vb@AranMulholland:不幸的是,是的:当时我有一个由另一个开发人员用VB编写的DAL,我正在用C构建后端。Net的美丽!哇,我不知道那是真的。看起来不错我现在正在看-我想我可以给它一个很快的测试-我会在完成后发布一些基准测试。类似于Rob Connery的东西:也很快,但它更多地处理动态对象。从我所读到的来看,Dapper的速度更快。关于Dapper,我看到的唯一负面的事情是它生成IL来映射对象,然后缓存它。因此,如果生成的IL中有错误,祝你好运。看看短小精悍的代码:到目前为止,它似乎相当快,没有问题。我对马克·格雷威尔的参与不抱多大期望。
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
}
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
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;
    }
}
[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