Преамбула:
- Все строки подключения к данным, подключения и т. д. создаются с помощью DbProviderFactories.
- Код смешанный 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;
}
}
Мы будем очень признательны за любые предложения по повышению производительности...
Обновлять
Я реализовал dapper-dot-net, как предложил @EtienneT - вот время поиска:
[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
while(Reader.Read())
в стиле Fx 2.0. Это должно дать вам представление о том, насколько дорого обходятся все эти размышления и косвенные действия. - person Henk Holterman   schedule 26.05.2011new TEntity()
пока что снаружи. После этого все ваши записи одинаковы? - person Henk Holterman   schedule 26.05.2011