mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-06-20 04:48:16 +08:00
## v0.4.16
- 增加 ISelect.AsType 实现弱类型查询,配合 Select<object>().AsType(实体类型); - 补充 ISelect.From<T2>; - 补充 ExpressionTree 单元测试; - 优化 ToList(a => new Dto()),会按优先级查询 Join 实体属性;
This commit is contained in:
@ -101,19 +101,27 @@ namespace FreeSql.Internal {
|
||||
} else {
|
||||
//dto 映射
|
||||
var dtoProps = _dicReadAnonymousFieldDtoPropertys.GetOrAdd(initExp.NewExpression.Type, dtoType => dtoType.GetProperties());
|
||||
var dtoTb0 = _tables.First();
|
||||
foreach (var dtoProp in dtoProps) {
|
||||
if (dtoTb0.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol)) {
|
||||
var child = new ReadAnonymousTypeInfo {
|
||||
Property = dtoProp,
|
||||
CsName = dtoProp.Name,
|
||||
CsType = dtoProp.PropertyType
|
||||
};
|
||||
parent.Childs.Add(child);
|
||||
ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtoTb0.Parameter, dtoTb0.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString);
|
||||
foreach (var dtTb in _tables) {
|
||||
if (dtTb.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol)) {
|
||||
var child = new ReadAnonymousTypeInfo {
|
||||
Property = dtoProp,
|
||||
CsName = dtoProp.Name,
|
||||
CsType = dtoProp.PropertyType
|
||||
};
|
||||
parent.Childs.Add(child);
|
||||
if (dtTb.Parameter != null)
|
||||
ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString);
|
||||
else {
|
||||
child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}";
|
||||
field.Append(", ").Append(child.DbField);
|
||||
if (index >= 0) field.Append(" as").Append(++index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parent.Childs.Any() == false) throw new Exception($"映射异常:{initExp.NewExpression.Type.Name} 没有一个属性名和 {dtoTb0.Table.Type.Name} 相同");
|
||||
if (parent.Childs.Any() == false) throw new Exception($"映射异常:{initExp.NewExpression.Type.Name} 没有一个属性名相同");
|
||||
}
|
||||
return true;
|
||||
case ExpressionType.New:
|
||||
@ -134,19 +142,27 @@ namespace FreeSql.Internal {
|
||||
//dto 映射
|
||||
parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
|
||||
var dtoProps = _dicReadAnonymousFieldDtoPropertys.GetOrAdd(newExp.Type, dtoType => dtoType.GetProperties());
|
||||
var dtoTb0 = _tables.First();
|
||||
foreach (var dtoProp in dtoProps) {
|
||||
if (dtoTb0.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol)) {
|
||||
var child = new ReadAnonymousTypeInfo {
|
||||
Property = dtoProp,
|
||||
CsName = dtoProp.Name,
|
||||
CsType = dtoProp.PropertyType
|
||||
};
|
||||
parent.Childs.Add(child);
|
||||
ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtoTb0.Parameter, dtoTb0.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString);
|
||||
foreach(var dtTb in _tables) {
|
||||
if (dtTb.Table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trydtocol)) {
|
||||
var child = new ReadAnonymousTypeInfo {
|
||||
Property = dtoProp,
|
||||
CsName = dtoProp.Name,
|
||||
CsType = dtoProp.PropertyType
|
||||
};
|
||||
parent.Childs.Add(child);
|
||||
if (dtTb.Parameter != null)
|
||||
ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString);
|
||||
else {
|
||||
child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}";
|
||||
field.Append(", ").Append(child.DbField);
|
||||
if (index >= 0) field.Append(" as").Append(++index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parent.Childs.Any() == false) throw new Exception($"映射异常:{newExp.Type.Name} 没有一个属性名和 {dtoTb0.Table.Type.Name} 相同");
|
||||
if (parent.Childs.Any() == false) throw new Exception($"映射异常:{newExp.Type.Name} 没有一个属性名相同");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
_commonExpression = commonExpression;
|
||||
_tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T1)), Alias = "a", On = null, Type = SelectTableInfoType.From });
|
||||
this.Where(_commonUtils.WhereObject(_tables.First().Table, "a.", dywhere));
|
||||
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure<T1>();
|
||||
if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure<T1>();
|
||||
}
|
||||
|
||||
public TSelect TrackToList(Action<object> track) {
|
||||
@ -519,6 +519,15 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
if (tableRule != null) _tableRules.Add(tableRule);
|
||||
return this as TSelect;
|
||||
}
|
||||
public TSelect AsType(Type entityType) {
|
||||
if (entityType == typeof(object)) throw new Exception("ISelect.AsType 参数不支持指定为 object");
|
||||
if (entityType == _tables[0].Table.Type) return this as TSelect;
|
||||
var newtb = _commonUtils.GetTableByEntity(entityType);
|
||||
if (newtb == null) throw new Exception("ISelect.AsType 参数错误,请传入正确的实体类型");
|
||||
_tables[0].Table = newtb;
|
||||
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType);
|
||||
return this as TSelect;
|
||||
}
|
||||
public abstract string ToSql(string field = null);
|
||||
|
||||
public TSelect Where(string sql, object parms = null) => this.WhereIf(true, sql, parms);
|
||||
|
@ -70,6 +70,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
return this.InternalAvgAsync<TMember>(column?.Body);
|
||||
}
|
||||
|
||||
public abstract ISelect<T1, T2> From<T2>(Expression<Func<ISelectFromExpression<T1>, T2, ISelectFromExpression<T1>>> exp) where T2 : class;// { this.InternalFrom(exp?.Body); var ret = new Select3Provider<T1, T2, T3>(_orm, _commonUtils, _commonExpression, null); Select0Provider<ISelect<T1>, T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||
public abstract ISelect<T1, T2, T3> From<T2, T3>(Expression<Func<ISelectFromExpression<T1>, T2, T3, ISelectFromExpression<T1>>> exp) where T2 : class where T3 : class;// { this.InternalFrom(exp?.Body); var ret = new Select3Provider<T1, T2, T3>(_orm, _commonUtils, _commonExpression, null); Select0Provider<ISelect<T1>, T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||
|
||||
public abstract ISelect<T1, T2, T3, T4> From<T2, T3, T4>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, ISelectFromExpression<T1>>> exp) where T2 : class where T3 : class where T4 : class;// { this.InternalFrom(exp?.Body); var ret = new Select4Provider<T1, T2, T3, T4>(_orm, _commonUtils, _commonExpression, null); Select0Provider<ISelect<T1>, T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||
|
@ -0,0 +1,152 @@
|
||||
using FreeSql.Internal.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
abstract class Select2Provider<T1, T2> : Select0Provider<ISelect<T1, T2>, T1>, ISelect<T1, T2>
|
||||
where T1 : class
|
||||
where T2 : class {
|
||||
|
||||
public Select2Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) {
|
||||
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2));
|
||||
_tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From });
|
||||
}
|
||||
|
||||
TMember ISelect<T1, T2>.Avg<TMember>(Expression<Func<T1, T2, TMember>> column) {
|
||||
if (column == null) return default(TMember);
|
||||
for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a];
|
||||
return this.InternalAvg<TMember>(column?.Body);
|
||||
}
|
||||
|
||||
Task<TMember> ISelect<T1, T2>.AvgAsync<TMember>(Expression<Func<T1, T2, TMember>> column) {
|
||||
if (column == null) return Task.FromResult(default(TMember));
|
||||
for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a];
|
||||
return this.InternalAvgAsync<TMember>(column?.Body);
|
||||
}
|
||||
|
||||
ISelectGrouping<TKey> ISelect<T1, T2>.GroupBy<TKey>(Expression<Func<T1, T2, TKey>> exp) {
|
||||
if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body);
|
||||
for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
|
||||
return this.InternalGroupBy<TKey>(exp?.Body);
|
||||
}
|
||||
|
||||
TMember ISelect<T1, T2>.Max<TMember>(Expression<Func<T1, T2, TMember>> column) {
|
||||
if (column == null) return default(TMember);
|
||||
for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a];
|
||||
return this.InternalMax<TMember>(column?.Body);
|
||||
}
|
||||
|
||||
Task<TMember> ISelect<T1, T2>.MaxAsync<TMember>(Expression<Func<T1, T2, TMember>> column) {
|
||||
if (column == null) return Task.FromResult(default(TMember));
|
||||
for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a];
|
||||
return this.InternalMaxAsync<TMember>(column?.Body);
|
||||
}
|
||||
|
||||
TMember ISelect<T1, T2>.Min<TMember>(Expression<Func<T1, T2, TMember>> column) {
|
||||
if (column == null) return default(TMember);
|
||||
for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a];
|
||||
return this.InternalMin<TMember>(column?.Body);
|
||||
}
|
||||
|
||||
Task<TMember> ISelect<T1, T2>.MinAsync<TMember>(Expression<Func<T1, T2, TMember>> column) {
|
||||
if (column == null) return Task.FromResult(default(TMember));
|
||||
for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a];
|
||||
return this.InternalMinAsync<TMember>(column?.Body);
|
||||
}
|
||||
|
||||
ISelect<T1, T2> ISelect<T1, T2>.OrderBy<TMember>(Expression<Func<T1, T2, TMember>> column) {
|
||||
if (column == null) this.InternalOrderBy(column?.Body);
|
||||
for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a];
|
||||
return this.InternalOrderBy(column?.Body);
|
||||
}
|
||||
|
||||
ISelect<T1, T2> ISelect<T1, T2>.OrderByDescending<TMember>(Expression<Func<T1, T2, TMember>> column) {
|
||||
if (column == null) this.InternalOrderBy(column?.Body);
|
||||
for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a];
|
||||
return this.InternalOrderByDescending(column?.Body);
|
||||
}
|
||||
|
||||
TMember ISelect<T1, T2>.Sum<TMember>(Expression<Func<T1, T2, TMember>> column) {
|
||||
if (column == null) this.InternalOrderBy(column?.Body);
|
||||
for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a];
|
||||
return this.InternalSum<TMember>(column?.Body);
|
||||
}
|
||||
|
||||
Task<TMember> ISelect<T1, T2>.SumAsync<TMember>(Expression<Func<T1, T2, TMember>> column) {
|
||||
if (column == null) this.InternalOrderBy(column?.Body);
|
||||
for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a];
|
||||
return this.InternalSumAsync<TMember>(column?.Body);
|
||||
}
|
||||
|
||||
TReturn ISelect<T1, T2>.ToAggregate<TReturn>(Expression<Func<ISelectGroupingAggregate<T1>, ISelectGroupingAggregate<T2>, TReturn>> select) {
|
||||
if (select == null) return default(TReturn);
|
||||
for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
|
||||
return this.InternalToAggregate<TReturn>(select?.Body);
|
||||
}
|
||||
|
||||
Task<TReturn> ISelect<T1, T2>.ToAggregateAsync<TReturn>(Expression<Func<ISelectGroupingAggregate<T1>, ISelectGroupingAggregate<T2>, TReturn>> select) {
|
||||
if (select == null) return Task.FromResult(default(TReturn));
|
||||
for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
|
||||
return this.InternalToAggregateAsync<TReturn>(select?.Body);
|
||||
}
|
||||
|
||||
List<TReturn> ISelect<T1, T2>.ToList<TReturn>(Expression<Func<T1, T2, TReturn>> select) {
|
||||
if (select == null) return this.InternalToList<TReturn>(select?.Body);
|
||||
for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
|
||||
return this.InternalToList<TReturn>(select?.Body);
|
||||
}
|
||||
|
||||
Task<List<TReturn>> ISelect<T1, T2>.ToListAsync<TReturn>(Expression<Func<T1, T2, TReturn>> select) {
|
||||
if (select == null) return this.InternalToListAsync<TReturn>(select?.Body);
|
||||
for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
|
||||
return this.InternalToListAsync<TReturn>(select?.Body);
|
||||
}
|
||||
|
||||
DataTable ISelect<T1, T2>.ToDataTable<TReturn>(Expression<Func<T1, T2, TReturn>> select) {
|
||||
if (select == null) return this.InternalToDataTable(select?.Body);
|
||||
for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
|
||||
return this.InternalToDataTable(select?.Body);
|
||||
}
|
||||
|
||||
Task<DataTable> ISelect<T1, T2>.ToDataTableAsync<TReturn>(Expression<Func<T1, T2, TReturn>> select) {
|
||||
if (select == null) return this.InternalToDataTableAsync(select?.Body);
|
||||
for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
|
||||
return this.InternalToDataTableAsync(select?.Body);
|
||||
}
|
||||
|
||||
string ISelect<T1, T2>.ToSql<TReturn>(Expression<Func<T1, T2, TReturn>> select) {
|
||||
if (select == null) return this.InternalToSql<TReturn>(select?.Body);
|
||||
for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
|
||||
return this.InternalToSql<TReturn>(select?.Body);
|
||||
}
|
||||
|
||||
ISelect<T1, T2> ISelect<T1, T2>.Where(Expression<Func<T1, T2, bool>> exp) {
|
||||
if (exp == null) return this.Where(null);
|
||||
for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
|
||||
return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
|
||||
}
|
||||
|
||||
ISelect<T1, T2> ISelect<T1, T2>.WhereIf(bool condition, Expression<Func<T1, T2, bool>> exp) {
|
||||
if (condition) return this.Where(null);
|
||||
if (exp == null) return this.Where(null);
|
||||
for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
|
||||
return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)) : this;
|
||||
}
|
||||
|
||||
bool ISelect<T1, T2>.Any(Expression<Func<T1, T2, bool>> exp) {
|
||||
if (exp == null) return this.Any();
|
||||
for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
|
||||
return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any();
|
||||
}
|
||||
|
||||
Task<bool> ISelect<T1, T2>.AnyAsync(Expression<Func<T1, T2, bool>> exp) {
|
||||
if (exp == null) return this.AnyAsync();
|
||||
for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
|
||||
return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync();
|
||||
}
|
||||
}
|
||||
}
|
@ -385,7 +385,7 @@ namespace FreeSql.Internal {
|
||||
}
|
||||
|
||||
if (isLazy) {
|
||||
cscode.Append(" public bool __lazy__").Append(pnv.Name).AppendLine(" = false;")
|
||||
cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;")
|
||||
.Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {");
|
||||
if (vp.Item2) { //get 重写
|
||||
cscode.Append(" get {\r\n")
|
||||
@ -460,7 +460,7 @@ namespace FreeSql.Internal {
|
||||
}
|
||||
|
||||
if (isLazy) {
|
||||
cscode.Append(" public bool __lazy__").Append(pnv.Name).AppendLine(" = false;")
|
||||
cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;")
|
||||
.Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {");
|
||||
if (vp.Item2) { //get 重写
|
||||
cscode.Append(" get {\r\n")
|
||||
@ -550,7 +550,7 @@ namespace FreeSql.Internal {
|
||||
}
|
||||
|
||||
if (isLazy) {
|
||||
cscode.Append(" public bool __lazy__").Append(pnv.Name).AppendLine(" = false;")
|
||||
cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;")
|
||||
.Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {");
|
||||
if (vp.Item2) { //get 重写
|
||||
cscode.Append(" get {\r\n")
|
||||
@ -1009,6 +1009,17 @@ namespace FreeSql.Internal {
|
||||
static MethodInfo MethodJTokenParse = typeof(JToken).GetMethod("Parse", new[] { typeof(string) });
|
||||
static MethodInfo MethodJObjectParse = typeof(JObject).GetMethod("Parse", new[] { typeof(string) });
|
||||
static MethodInfo MethodJArrayParse = typeof(JArray).GetMethod("Parse", new[] { typeof(string) });
|
||||
static MethodInfo MethodSByteTryParse = typeof(sbyte).GetMethod("TryParse", new[] { typeof(string), typeof(sbyte).MakeByRefType() });
|
||||
static MethodInfo MethodShortTryParse = typeof(short).GetMethod("TryParse", new[] { typeof(string), typeof(short).MakeByRefType() });
|
||||
static MethodInfo MethodIntTryParse = typeof(int).GetMethod("TryParse", new[] { typeof(string), typeof(int).MakeByRefType() });
|
||||
static MethodInfo MethodLongTryParse = typeof(long).GetMethod("TryParse", new[] { typeof(string), typeof(long).MakeByRefType() });
|
||||
static MethodInfo MethodByteTryParse = typeof(byte).GetMethod("TryParse", new[] { typeof(string), typeof(byte).MakeByRefType() });
|
||||
static MethodInfo MethodUShortTryParse = typeof(ushort).GetMethod("TryParse", new[] { typeof(string), typeof(ushort).MakeByRefType() });
|
||||
static MethodInfo MethodUIntTryParse = typeof(uint).GetMethod("TryParse", new[] { typeof(string), typeof(uint).MakeByRefType() });
|
||||
static MethodInfo MethodULongTryParse = typeof(ulong).GetMethod("TryParse", new[] { typeof(string), typeof(ulong).MakeByRefType() });
|
||||
static MethodInfo MethodDoubleTryParse = typeof(double).GetMethod("TryParse", new[] { typeof(string), typeof(double).MakeByRefType() });
|
||||
static MethodInfo MethodFloatTryParse = typeof(float).GetMethod("TryParse", new[] { typeof(string), typeof(float).MakeByRefType() });
|
||||
static MethodInfo MethodDecimalTryParse = typeof(decimal).GetMethod("TryParse", new[] { typeof(string), typeof(decimal).MakeByRefType() });
|
||||
public static Expression GetDataReaderValueBlockExpression(Type type, Expression value) {
|
||||
var returnTarget = Expression.Label(typeof(object));
|
||||
var valueExp = Expression.Variable(typeof(object), "locvalue");
|
||||
@ -1024,7 +1035,7 @@ namespace FreeSql.Internal {
|
||||
var label = Expression.Label(typeof(int));
|
||||
return Expression.IfThenElse(
|
||||
Expression.TypeEqual(valueExp, type),
|
||||
Expression.Return(returnTarget, valueExp),
|
||||
Expression.Return(returnTarget, valueExp),
|
||||
Expression.Block(
|
||||
new[] { arrNewExp, arrExp, arrLenExp, arrXExp, arrReadValExp },
|
||||
Expression.Assign(arrExp, Expression.TypeAs(valueExp, typeof(Array))),
|
||||
@ -1051,10 +1062,15 @@ namespace FreeSql.Internal {
|
||||
)
|
||||
);
|
||||
}
|
||||
var typeOrg = type;
|
||||
if (type.IsNullableType()) type = type.GenericTypeArguments.First();
|
||||
if (type.IsEnum) return Expression.Return(returnTarget, Expression.Call(MethodEnumParse, Expression.Constant(type, typeof(Type)), Expression.Call(MethodToString, valueExp), Expression.Constant(true, typeof(bool))));
|
||||
switch(type.FullName) {
|
||||
case "System.Guid": return Expression.IfThenElse(
|
||||
Expression tryparseExp = null;
|
||||
Expression tryparseBooleanExp = null;
|
||||
ParameterExpression tryparseVarExp = null;
|
||||
switch (type.FullName) {
|
||||
case "System.Guid":
|
||||
return Expression.IfThenElse(
|
||||
Expression.TypeEqual(valueExp, type),
|
||||
Expression.Return(returnTarget, valueExp),
|
||||
Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodGuidParse, Expression.Convert(valueExp, typeof(string))), typeof(object)))
|
||||
@ -1069,22 +1085,190 @@ namespace FreeSql.Internal {
|
||||
case "Newtonsoft.Json.Linq.JObject": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJObjectParse, Expression.Convert(valueExp, typeof(string))), typeof(JObject)));
|
||||
case "Newtonsoft.Json.Linq.JArray": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJArrayParse, Expression.Convert(valueExp, typeof(string))), typeof(JArray)));
|
||||
case "Npgsql.LegacyPostgis.PostgisGeometry": return Expression.Return(returnTarget, valueExp);
|
||||
case "System.TimeSpan": return Expression.IfThenElse(
|
||||
case "System.TimeSpan":
|
||||
return Expression.IfThenElse(
|
||||
Expression.TypeEqual(valueExp, type),
|
||||
Expression.Return(returnTarget, valueExp),
|
||||
Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodTimeSpanFromSeconds, Expression.Call(MethodDoubleParse, Expression.Call(MethodToString, valueExp))), typeof(object)))
|
||||
);
|
||||
case "System.SByte":
|
||||
tryparseExp = Expression.Block(
|
||||
new[] { tryparseVarExp = Expression.Variable(typeof(sbyte)) },
|
||||
new Expression[] {
|
||||
Expression.IfThenElse(
|
||||
Expression.IsTrue(Expression.Call(MethodSByteTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)),
|
||||
Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))),
|
||||
Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object)))
|
||||
)
|
||||
}
|
||||
);
|
||||
break;
|
||||
case "System.Int16":
|
||||
tryparseExp = Expression.Block(
|
||||
new[] { tryparseVarExp = Expression.Variable(typeof(short)) },
|
||||
new Expression[] {
|
||||
Expression.IfThenElse(
|
||||
Expression.IsTrue(Expression.Call(MethodShortTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)),
|
||||
Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))),
|
||||
Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object)))
|
||||
)
|
||||
}
|
||||
);
|
||||
break;
|
||||
case "System.Int32":
|
||||
tryparseExp = Expression.Block(
|
||||
new[] { tryparseVarExp = Expression.Variable(typeof(int)) },
|
||||
new Expression[] {
|
||||
Expression.IfThenElse(
|
||||
Expression.IsTrue(Expression.Call(MethodIntTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)),
|
||||
Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))),
|
||||
Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object)))
|
||||
)
|
||||
}
|
||||
);
|
||||
break;
|
||||
case "System.Int64":
|
||||
tryparseExp = Expression.Block(
|
||||
new[] { tryparseVarExp = Expression.Variable(typeof(long)) },
|
||||
new Expression[] {
|
||||
Expression.IfThenElse(
|
||||
Expression.IsTrue(Expression.Call(MethodLongTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)),
|
||||
Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))),
|
||||
Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object)))
|
||||
)
|
||||
}
|
||||
);
|
||||
break;
|
||||
case "System.Byte":
|
||||
tryparseExp = Expression.Block(
|
||||
new[] { tryparseVarExp = Expression.Variable(typeof(byte)) },
|
||||
new Expression[] {
|
||||
Expression.IfThenElse(
|
||||
Expression.IsTrue(Expression.Call(MethodByteTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)),
|
||||
Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))),
|
||||
Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object)))
|
||||
)
|
||||
}
|
||||
);
|
||||
break;
|
||||
case "System.UInt16":
|
||||
tryparseExp = Expression.Block(
|
||||
new[] { tryparseVarExp = Expression.Variable(typeof(ushort)) },
|
||||
new Expression[] {
|
||||
Expression.IfThenElse(
|
||||
Expression.IsTrue(Expression.Call(MethodUShortTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)),
|
||||
Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))),
|
||||
Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object)))
|
||||
)
|
||||
}
|
||||
);
|
||||
break;
|
||||
case "System.UInt32":
|
||||
tryparseExp = Expression.Block(
|
||||
new[] { tryparseVarExp = Expression.Variable(typeof(uint)) },
|
||||
new Expression[] {
|
||||
Expression.IfThenElse(
|
||||
Expression.IsTrue(Expression.Call(MethodUIntTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)),
|
||||
Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))),
|
||||
Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object)))
|
||||
)
|
||||
}
|
||||
);
|
||||
break;
|
||||
case "System.UInt64":
|
||||
tryparseExp = Expression.Block(
|
||||
new[] { tryparseVarExp = Expression.Variable(typeof(ulong)) },
|
||||
new Expression[] {
|
||||
Expression.IfThenElse(
|
||||
Expression.IsTrue(Expression.Call(MethodULongTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)),
|
||||
Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))),
|
||||
Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object)))
|
||||
)
|
||||
}
|
||||
);
|
||||
break;
|
||||
case "System.Single":
|
||||
tryparseExp = Expression.Block(
|
||||
new[] { tryparseVarExp = Expression.Variable(typeof(float)) },
|
||||
new Expression[] {
|
||||
Expression.IfThenElse(
|
||||
Expression.IsTrue(Expression.Call(MethodFloatTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)),
|
||||
Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))),
|
||||
Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object)))
|
||||
)
|
||||
}
|
||||
);
|
||||
break;
|
||||
case "System.Double":
|
||||
tryparseExp = Expression.Block(
|
||||
new[] { tryparseVarExp = Expression.Variable(typeof(double)) },
|
||||
new Expression[] {
|
||||
Expression.IfThenElse(
|
||||
Expression.IsTrue(Expression.Call(MethodDoubleTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)),
|
||||
Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))),
|
||||
Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object)))
|
||||
)
|
||||
}
|
||||
);
|
||||
break;
|
||||
case "System.Decimal":
|
||||
tryparseExp = Expression.Block(
|
||||
new[] { tryparseVarExp = Expression.Variable(typeof(decimal)) },
|
||||
new Expression[] {
|
||||
Expression.IfThenElse(
|
||||
Expression.IsTrue(Expression.Call(MethodDecimalTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)),
|
||||
Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))),
|
||||
Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object)))
|
||||
)
|
||||
}
|
||||
);
|
||||
break;
|
||||
case "System.Boolean":
|
||||
tryparseBooleanExp = Expression.Return(returnTarget,
|
||||
Expression.Convert(
|
||||
Expression.Not(
|
||||
Expression.Or(
|
||||
Expression.Equal(Expression.Convert(valueExp, typeof(string)), Expression.Constant("False")),
|
||||
Expression.Or(
|
||||
Expression.Equal(Expression.Convert(valueExp, typeof(string)), Expression.Constant("false")),
|
||||
Expression.Equal(Expression.Convert(valueExp, typeof(string)), Expression.Constant("0"))))),
|
||||
typeof(object))
|
||||
);
|
||||
break;
|
||||
}
|
||||
Expression switchExp = null;
|
||||
if (tryparseExp != null)
|
||||
switchExp = Expression.Switch(
|
||||
Expression.Constant(type),
|
||||
Expression.SwitchCase(tryparseExp,
|
||||
Expression.Constant(typeof(sbyte)), Expression.Constant(typeof(short)), Expression.Constant(typeof(int)), Expression.Constant(typeof(long)),
|
||||
Expression.Constant(typeof(byte)), Expression.Constant(typeof(ushort)), Expression.Constant(typeof(uint)), Expression.Constant(typeof(ulong)),
|
||||
Expression.Constant(typeof(double)), Expression.Constant(typeof(float)), Expression.Constant(typeof(decimal))),
|
||||
Expression.SwitchCase(Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))), Expression.Constant(type))
|
||||
);
|
||||
else if (tryparseBooleanExp != null)
|
||||
switchExp = Expression.Switch(
|
||||
Expression.Constant(type),
|
||||
Expression.SwitchCase(tryparseBooleanExp, Expression.Constant(typeof(bool))),
|
||||
Expression.SwitchCase(Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))), Expression.Constant(type))
|
||||
);
|
||||
else
|
||||
switchExp = Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type))));
|
||||
|
||||
return Expression.IfThenElse(
|
||||
Expression.TypeEqual(valueExp, type),
|
||||
Expression.Return(returnTarget, valueExp),
|
||||
Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type))))
|
||||
Expression.IfThenElse(
|
||||
Expression.TypeEqual(valueExp, typeof(string)),
|
||||
switchExp,
|
||||
Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type))))
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
return Expression.Block(
|
||||
new[] { valueExp },
|
||||
Expression.Assign(valueExp, value),
|
||||
Expression.Assign(valueExp, Expression.Convert(value, typeof(object))),
|
||||
Expression.IfThenElse(
|
||||
Expression.Or(
|
||||
Expression.Equal(valueExp, Expression.Constant(null)),
|
||||
@ -1097,9 +1281,9 @@ namespace FreeSql.Internal {
|
||||
);
|
||||
}
|
||||
public static object GetDataReaderValue(Type type, object value) {
|
||||
if (value == null || value == DBNull.Value) return null;
|
||||
//if (value == null || value == DBNull.Value) return Activator.CreateInstance(type);
|
||||
if (type == null) return value;
|
||||
var func = _dicGetDataReaderValue.GetOrAdd(type, k1 => new ConcurrentDictionary<Type, Func<object, object>>()).GetOrAdd(value.GetType(), valueType => {
|
||||
var func = _dicGetDataReaderValue.GetOrAdd(type, k1 => new ConcurrentDictionary<Type, Func<object, object>>()).GetOrAdd(value?.GetType() ?? type, valueType => {
|
||||
var parmExp = Expression.Parameter(typeof(object), "value");
|
||||
var exp = GetDataReaderValueBlockExpression(type, parmExp);
|
||||
return Expression.Lambda<Func<object, object>>(exp, parmExp).Compile();
|
||||
@ -1233,7 +1417,7 @@ namespace FreeSql.Internal {
|
||||
#endregion
|
||||
}
|
||||
internal static object GetDataReaderValue22(Type type, object value) {
|
||||
if (value == null || value == DBNull.Value) return null;
|
||||
if (value == null || value == DBNull.Value) return Activator.CreateInstance(type);
|
||||
if (type.FullName == "System.Byte[]") return value;
|
||||
if (type.IsArray) {
|
||||
var elementType = type.GetElementType();
|
||||
|
Reference in New Issue
Block a user