mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-06-19 12:28:15 +08:00
Reflection 替换 ExpressionTree,单元测试已通过
This commit is contained in:
@ -62,23 +62,19 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
if (isThrowException) throw e;
|
||||
}
|
||||
|
||||
public List<T> Query<T>(string sql, object parms = null) => Query<T>(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||
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);
|
||||
var defaultValue = default(T);
|
||||
ExecuteReader(dr => {
|
||||
if (names.Any() == false)
|
||||
for (var a = 0; a < dr.FieldCount; a++) names.Add(dr.GetName(a), a);
|
||||
object[] values = new object[names.Count];
|
||||
dr.GetValues(values);
|
||||
var read = Utils.ExecuteArrayRowReadClassOrTuple(type, names, values, 0);
|
||||
ret.Add(read.Value == null ? defaultValue : (T)read.Value);
|
||||
ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(type, names, dr, 0).Value);
|
||||
}, cmdType, cmdText, cmdParms);
|
||||
return ret;
|
||||
}
|
||||
public void ExecuteReader(Action<DbDataReader> readerHander, string sql, object parms = null) => ExecuteReader(readerHander, CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||
public void ExecuteReader(Action<DbDataReader> readerHander, string cmdText, object parms = null) => ExecuteReader(readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
|
||||
public void ExecuteReader(Action<DbDataReader> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
||||
var dt = DateTime.Now;
|
||||
var logtxt = new StringBuilder();
|
||||
@ -172,7 +168,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
LoggerException(pool, pc.cmd, ex, dt, logtxt);
|
||||
pc.cmd.Parameters.Clear();
|
||||
}
|
||||
public object[][] ExecuteArray(string sql, object parms = null) => ExecuteArray(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||
public object[][] ExecuteArray(string cmdText, object parms = null) => ExecuteArray(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
|
||||
public object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
||||
List<object[]> ret = new List<object[]>();
|
||||
ExecuteReader(dr => {
|
||||
@ -182,7 +178,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
}, cmdType, cmdText, cmdParms);
|
||||
return ret.ToArray();
|
||||
}
|
||||
public DataTable ExecuteDataTable(string sql, object parms = null) => ExecuteDataTable(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||
public DataTable ExecuteDataTable(string cmdText, object parms = null) => ExecuteDataTable(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
|
||||
public DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
||||
var ret = new DataTable();
|
||||
ExecuteReader(dr => {
|
||||
@ -194,7 +190,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
}, cmdType, cmdText, cmdParms);
|
||||
return ret;
|
||||
}
|
||||
public int ExecuteNonQuery(string sql, object parms = null) => ExecuteNonQuery(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||
public int ExecuteNonQuery(string cmdText, object parms = null) => ExecuteNonQuery(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
|
||||
public int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
||||
var dt = DateTime.Now;
|
||||
var logtxt = new StringBuilder();
|
||||
@ -219,7 +215,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
pc.cmd.Parameters.Clear();
|
||||
return val;
|
||||
}
|
||||
public object ExecuteScalar(string sql, object parms = null) => ExecuteScalar(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||
public object ExecuteScalar(string cmdText, object parms = null) => ExecuteScalar(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
|
||||
public object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
||||
var dt = DateTime.Now;
|
||||
var logtxt = new StringBuilder();
|
||||
|
@ -9,25 +9,20 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
partial class AdoProvider {
|
||||
public Task<List<T>> QueryAsync<T>(string sql, object parms = null) => QueryAsync<T>(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||
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 ds = new List<object[]>();
|
||||
await ExecuteReaderAsync(async dr => {
|
||||
var ret = new List<T>();
|
||||
var type = typeof(T);
|
||||
await ExecuteReaderAsync(dr => {
|
||||
if (names.Any() == false)
|
||||
for (var a = 0; a < dr.FieldCount; a++) names.Add(dr.GetName(a), a);
|
||||
object[] values = new object[dr.FieldCount];
|
||||
for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync<object>(a);
|
||||
ds.Add(values);
|
||||
ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(type, names, dr, 0).Value);
|
||||
return Task.CompletedTask;
|
||||
}, cmdType, cmdText, cmdParms);
|
||||
var ret = new List<T>();
|
||||
foreach (var row in ds) {
|
||||
var read = Utils.ExecuteArrayRowReadClassOrTuple(typeof(T), names, row);
|
||||
ret.Add(read.Value == null ? default(T) : (T) read.Value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
public Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, string sql, object parms = null) => ExecuteReaderAsync(readerHander, CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||
public Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
|
||||
async public Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
||||
var dt = DateTime.Now;
|
||||
var logtxt = new StringBuilder();
|
||||
@ -121,7 +116,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
LoggerException(pool, cmd, ex, dt, logtxt);
|
||||
cmd.Parameters.Clear();
|
||||
}
|
||||
public Task ExecuteArrayAsync(string sql, object parms = null) => ExecuteArrayAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||
public Task<object[][]> ExecuteArrayAsync(string cmdText, object parms = null) => ExecuteArrayAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
|
||||
async public Task<object[][]> ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
||||
List<object[]> ret = new List<object[]>();
|
||||
await ExecuteReaderAsync(async dr => {
|
||||
@ -131,7 +126,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
}, cmdType, cmdText, cmdParms);
|
||||
return ret.ToArray();
|
||||
}
|
||||
public Task<DataTable> ExecuteDataTableAsync(string sql, object parms = null) => ExecuteDataTableAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||
public Task<DataTable> ExecuteDataTableAsync(string cmdText, object parms = null) => ExecuteDataTableAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
|
||||
async public Task<DataTable> ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
||||
var ret = new DataTable();
|
||||
await ExecuteReaderAsync(async dr => {
|
||||
@ -143,7 +138,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
}, cmdType, cmdText, cmdParms);
|
||||
return ret;
|
||||
}
|
||||
public Task<int> ExecuteNonQueryAsync(string sql, object parms = null) => ExecuteNonQueryAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||
public Task<int> ExecuteNonQueryAsync(string cmdText, object parms = null) => ExecuteNonQueryAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
|
||||
async public Task<int> ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
||||
var dt = DateTime.Now;
|
||||
var logtxt = new StringBuilder();
|
||||
@ -168,7 +163,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
cmd.Parameters.Clear();
|
||||
return val;
|
||||
}
|
||||
public Task<object> ExecuteScalarAsync(string sql, object parms = null) => ExecuteScalarAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||
public Task<object> ExecuteScalarAsync(string cmdText, object parms = null) => ExecuteScalarAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
|
||||
async public Task<object> ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
||||
var dt = DateTime.Now;
|
||||
var logtxt = new StringBuilder();
|
||||
|
@ -147,11 +147,10 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
return _orm.Cache.Shell(_cache.key, _cache.seconds, () => {
|
||||
List<TTuple> ret = new List<TTuple>();
|
||||
Type type = typeof(TTuple);
|
||||
var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql, _params.ToArray());
|
||||
foreach (var dr in ds) {
|
||||
_orm.Ado.ExecuteReader(dr => {
|
||||
var read = Utils.ExecuteArrayRowReadClassOrTuple(type, null, dr);
|
||||
ret.Add(read.Value == null ? default(TTuple) : (TTuple)read.Value);
|
||||
}
|
||||
ret.Add((TTuple)read.Value);
|
||||
}, CommandType.Text, sql, _params.ToArray());
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
@ -162,19 +161,40 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
return _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => {
|
||||
List<TTuple> ret = new List<TTuple>();
|
||||
Type type = typeof(TTuple);
|
||||
var ds = await _orm.Ado.ExecuteArrayAsync(CommandType.Text, sql, _params.ToArray());
|
||||
foreach (var dr in ds) {
|
||||
await _orm.Ado.ExecuteReaderAsync(dr => {
|
||||
var read = Utils.ExecuteArrayRowReadClassOrTuple(type, null, dr);
|
||||
ret.Add(read.Value == null ? default(TTuple) : (TTuple)read.Value);
|
||||
}
|
||||
ret.Add((TTuple)read.Value);
|
||||
return Task.CompletedTask;
|
||||
}, CommandType.Text, sql, _params.ToArray());
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
public List<T1> ToList() {
|
||||
return this.ToListMapReader<T1>(this.GetAllField());
|
||||
var af = this.GetAllFieldExpressionTree();
|
||||
var sql = this.ToSql(af.Field);
|
||||
if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
|
||||
|
||||
return _orm.Cache.Shell(_cache.key, _cache.seconds, () => {
|
||||
List<T1> ret = new List<T1>();
|
||||
_orm.Ado.ExecuteReader(dr => {
|
||||
ret.Add(af.Read(dr));
|
||||
}, CommandType.Text, sql, _params.ToArray());
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
public Task<List<T1>> ToListAsync() {
|
||||
return this.ToListMapReaderAsync<T1>(this.GetAllField());
|
||||
async public Task<List<T1>> ToListAsync() {
|
||||
var af = this.GetAllFieldExpressionTree();
|
||||
var sql = this.ToSql(af.Field);
|
||||
if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
|
||||
|
||||
return await _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => {
|
||||
List<T1> ret = new List<T1>();
|
||||
await _orm.Ado.ExecuteReaderAsync(dr => {
|
||||
ret.Add(af.Read(dr));
|
||||
return Task.CompletedTask;
|
||||
}, CommandType.Text, sql, _params.ToArray());
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
public T1 ToOne() {
|
||||
this.Limit(1);
|
||||
@ -189,27 +209,30 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
var sql = this.ToSql(af.field);
|
||||
if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
|
||||
|
||||
var drarr = _orm.Cache.Shell(_cache.key, _cache.seconds, () => _orm.Ado.ExecuteArray(CommandType.Text, sql, _params.ToArray()));
|
||||
var ret = new List<TReturn>();
|
||||
for (var a = 0; a < drarr.Length; a++) {
|
||||
var dr = drarr[a];
|
||||
var index = -1;
|
||||
ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index));
|
||||
}
|
||||
return ret;
|
||||
return _orm.Cache.Shell(_cache.key, _cache.seconds, () => {
|
||||
List<TReturn> ret = new List<TReturn>();
|
||||
Type type = typeof(TReturn);
|
||||
_orm.Ado.ExecuteReader(dr => {
|
||||
var index = -1;
|
||||
ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index));
|
||||
}, CommandType.Text, sql, _params.ToArray());
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
async protected Task<List<TReturn>> ToListMapReaderAsync<TReturn>((ReadAnonymousTypeInfo map, string field) af) {
|
||||
var sql = this.ToSql(af.field);
|
||||
if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
|
||||
|
||||
var drarr = await _orm.Cache.ShellAsync(_cache.key, _cache.seconds, () => _orm.Ado.ExecuteArrayAsync(CommandType.Text, sql, _params.ToArray()));
|
||||
var ret = new List<TReturn>();
|
||||
for (var a = 0; a < drarr.Length; a++) {
|
||||
var dr = drarr[a];
|
||||
var index = -1;
|
||||
ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index));
|
||||
}
|
||||
return ret;
|
||||
return await _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => {
|
||||
List<TReturn> ret = new List<TReturn>();
|
||||
Type type = typeof(TReturn);
|
||||
await _orm.Ado.ExecuteReaderAsync(dr => {
|
||||
var index = -1;
|
||||
ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index));
|
||||
return Task.CompletedTask;
|
||||
}, CommandType.Text, sql, _params.ToArray());
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
protected (ReadAnonymousTypeInfo map, string field) GetExpressionField(Expression newexp) {
|
||||
var map = new ReadAnonymousTypeInfo();
|
||||
@ -219,15 +242,113 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
_commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null);
|
||||
return (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null);
|
||||
}
|
||||
protected (ReadAnonymousTypeInfo map, string field) GetAllField() {
|
||||
var type = typeof(T1);
|
||||
var map = new ReadAnonymousTypeInfo { Consturctor = type.GetConstructor(new Type[0]), ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties };
|
||||
static ConcurrentDictionary<Type, ConstructorInfo> _dicConstructor = new ConcurrentDictionary<Type, ConstructorInfo>();
|
||||
static ConcurrentDictionary<string, GetAllFieldExpressionTreeInfo> _dicGetAllFieldExpressionTree = new ConcurrentDictionary<string, GetAllFieldExpressionTreeInfo>();
|
||||
public class GetAllFieldExpressionTreeInfo {
|
||||
public string Field { get; set; }
|
||||
public Func<DbDataReader, T1> Read { get; set; }
|
||||
}
|
||||
protected GetAllFieldExpressionTreeInfo GetAllFieldExpressionTree() {
|
||||
var key = string.Join("+", _tables.Select(a => $"{a.Table.DbName}-{a.Alias}"));
|
||||
return _dicGetAllFieldExpressionTree.GetOrAdd(key, s => {
|
||||
var type = _tables.First().Table.Type;
|
||||
|
||||
var rowExp = Expression.Parameter(typeof(DbDataReader), "row");
|
||||
var returnTarget = Expression.Label(type);
|
||||
var retExp = Expression.Variable(type, "ret");
|
||||
var dataIndexExp = Expression.Variable(typeof(int), "dataIndex");
|
||||
var readExp = Expression.Variable(typeof(Utils.RowInfo), "read");
|
||||
var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue);
|
||||
var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex);
|
||||
var blockExp = new List<Expression>();
|
||||
var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First();
|
||||
blockExp.AddRange(new Expression[] {
|
||||
Expression.Assign(retExp, Expression.New(ctor, ctor.GetParameters().Select(a => Expression.Default(a.ParameterType)))),
|
||||
Expression.Assign(dataIndexExp, Expression.Constant(0))
|
||||
});
|
||||
|
||||
var field = new StringBuilder();
|
||||
var dicfield = new Dictionary<string, bool>();
|
||||
var tb = _tables.First();
|
||||
var index = 0;
|
||||
var ps = _tables.First().Table.Properties;
|
||||
foreach (var prop in ps.Values) {
|
||||
if (tb.Table.ColumnsByCs.TryGetValue(prop.Name, out var col)) { //普通字段
|
||||
if (index > 0) field.Append(", ");
|
||||
var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name);
|
||||
field.Append(_commonUtils.QuoteReadColumn(col.CsType, $"{tb.Alias}.{quoteName}"));
|
||||
++index;
|
||||
if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index);
|
||||
else dicfield.Add(quoteName, true);
|
||||
} else {
|
||||
var tb2 = _tables.Where(a => a.Table.Type == prop.PropertyType && a.Alias.Contains(prop.Name)).FirstOrDefault();
|
||||
if (tb2 == null && ps.Where(pw => pw.Value.PropertyType == prop.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == prop.PropertyType).FirstOrDefault();
|
||||
if (tb2 == null) continue;
|
||||
foreach (var col2 in tb2.Table.Columns.Values) {
|
||||
if (index > 0) field.Append(", ");
|
||||
var quoteName = _commonUtils.QuoteSqlName(col2.Attribute.Name);
|
||||
field.Append(_commonUtils.QuoteReadColumn(col2.CsType, $"{tb2.Alias}.{quoteName}"));
|
||||
++index;
|
||||
if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index);
|
||||
else dicfield.Add(quoteName, true);
|
||||
}
|
||||
}
|
||||
//只读到二级属性
|
||||
var propGetSetMethod = prop.GetSetMethod();
|
||||
Expression readExpAssign = null; //加速缓存
|
||||
if (prop.PropertyType.IsArray) readExpAssign = Expression.New(Utils.RowInfo.Constructor,
|
||||
Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }),
|
||||
Expression.Add(dataIndexExp, Expression.Constant(1))
|
||||
);
|
||||
else {
|
||||
var proptypeGeneric = prop.PropertyType;
|
||||
if (proptypeGeneric.FullName.StartsWith("System.Nullable`1[")) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First();
|
||||
if (proptypeGeneric.IsEnum ||
|
||||
Utils.dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(Utils.RowInfo.Constructor,
|
||||
Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }),
|
||||
Expression.Add(dataIndexExp, Expression.Constant(1))
|
||||
);
|
||||
else {
|
||||
readExpAssign = Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Constant(null, typeof(Dictionary<string, int>)), rowExp, dataIndexExp });
|
||||
}
|
||||
}
|
||||
blockExp.AddRange(new Expression[] {
|
||||
//以下注释部分为【严格读取】,会损失一点性能
|
||||
//Expression.IfThen(Expression.Not(Expression.And(
|
||||
// Expression.NotEqual(namesExp, Expression.Constant(null)),
|
||||
// Expression.Not(Expression.Call(namesExp, namesExp.Type.GetMethod("TryGetValue"), Expression.Constant(prop.Name), tryidxExp)))),
|
||||
// Expression.Block(
|
||||
Expression.Assign(readExp, readExpAssign),
|
||||
Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
|
||||
Expression.Assign(dataIndexExp, readExpDataIndex)),
|
||||
Expression.IfThenElse(Expression.Equal(readExpValue, Expression.Constant(null)),
|
||||
Expression.Call(retExp, propGetSetMethod, Expression.Default(prop.PropertyType)),
|
||||
Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)))
|
||||
// )
|
||||
//)
|
||||
});
|
||||
}
|
||||
blockExp.AddRange(new Expression[] {
|
||||
Expression.Return(returnTarget, retExp),
|
||||
Expression.Label(returnTarget, Expression.Default(type))
|
||||
});
|
||||
return new GetAllFieldExpressionTreeInfo {
|
||||
Field = field.ToString(),
|
||||
Read = Expression.Lambda<Func<DbDataReader, T1>>(Expression.Block(new[] { retExp, dataIndexExp, readExp }, blockExp), new[] { rowExp }).Compile()
|
||||
};
|
||||
});
|
||||
}
|
||||
protected (ReadAnonymousTypeInfo map, string field) GetAllFieldReflection() {
|
||||
var type = _tables.First().Table.Type;
|
||||
var constructor = _dicConstructor.GetOrAdd(type, s => type.GetConstructor(new Type[0]));
|
||||
var map = new ReadAnonymousTypeInfo { Consturctor = constructor, ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties };
|
||||
|
||||
var field = new StringBuilder();
|
||||
var dicfield = new Dictionary<string, bool>();
|
||||
var tb = _tables.First();
|
||||
var index = 0;
|
||||
var ps = type.GetProperties();
|
||||
foreach (var p in ps) {
|
||||
var ps = _tables.First().Table.Properties;
|
||||
foreach (var p in ps.Values) {
|
||||
var child = new ReadAnonymousTypeInfo { Property = p, CsName = p.Name };
|
||||
if (tb.Table.ColumnsByCs.TryGetValue(p.Name, out var col)) { //普通字段
|
||||
if (index > 0) field.Append(", ");
|
||||
@ -238,7 +359,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
else dicfield.Add(quoteName, true);
|
||||
} else {
|
||||
var tb2 = _tables.Where(a => a.Table.Type == p.PropertyType && a.Alias.Contains(p.Name)).FirstOrDefault();
|
||||
if (tb2 == null && ps.Where(pw => pw.PropertyType == p.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == p.PropertyType).FirstOrDefault();
|
||||
if (tb2 == null && ps.Where(pw => pw.Value.PropertyType == p.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == p.PropertyType).FirstOrDefault();
|
||||
if (tb2 == null) continue;
|
||||
child.Consturctor = tb2.Table.Type.GetConstructor(new Type[0]);
|
||||
child.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
|
||||
|
Reference in New Issue
Block a user