ExpressionTree 优化告一段落

This commit is contained in:
28810
2019-01-19 15:21:04 +08:00
parent 0068474992
commit 56d79c9696
5 changed files with 399 additions and 273 deletions

View File

@ -2,11 +2,13 @@
using SafeObjectPool;
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Data;
using System.Data.Common;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Reflection;
namespace FreeSql.Internal.CommonProvider {
abstract partial class AdoProvider : IAdo {
@ -62,15 +64,21 @@ namespace FreeSql.Internal.CommonProvider {
if (isThrowException) throw e;
}
internal static ConcurrentDictionary<Type, Dictionary<string, PropertyInfo>> dicQueryTypeGetProperties = new ConcurrentDictionary<Type, Dictionary<string, PropertyInfo>>();
public List<T> Query<T>(string cmdText, object parms = null) => Query<T>(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
public List<T> Query<T>(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
var names = new Dictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);
var ret = new List<T>();
var type = typeof(T);
int[] indexes = null;
var props = dicQueryTypeGetProperties.GetOrAdd(type, k => type.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase));
ExecuteReader(dr => {
if (names.Any() == false)
for (var a = 0; a < dr.FieldCount; a++) names.Add(dr.GetName(a), a);
ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(type, names, dr, 0).Value);
if (indexes == null) {
var idxs = new List<int>();
for (var a = 0; a < dr.FieldCount; a++)
if (props.ContainsKey(dr.GetName(a))) idxs.Add(a);
indexes = idxs.ToArray();
}
ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(type, indexes, dr, 0).Value);
}, cmdType, cmdText, cmdParms);
return ret;
}

View File

@ -11,13 +11,18 @@ namespace FreeSql.Internal.CommonProvider {
partial class AdoProvider {
public Task<List<T>> QueryAsync<T>(string cmdText, object parms = null) => QueryAsync<T>(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
async public Task<List<T>> QueryAsync<T>(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
var names = new Dictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);
var ret = new List<T>();
var type = typeof(T);
int[] indexes = null;
var props = dicQueryTypeGetProperties.GetOrAdd(type, k => type.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase));
await ExecuteReaderAsync(dr => {
if (names.Any() == false)
for (var a = 0; a < dr.FieldCount; a++) names.Add(dr.GetName(a), a);
ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(type, names, dr, 0).Value);
if (indexes == null) {
var idxs = new List<int>();
for (var a = 0; a < dr.FieldCount; a++)
if (props.ContainsKey(dr.GetName(a))) idxs.Add(a);
indexes = idxs.ToArray();
}
ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(type, indexes, dr, 0).Value);
return Task.CompletedTask;
}, cmdType, cmdText, cmdParms);
return ret;