mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
- 优化 实体基类的属性位置,优先排在最前面; #164
- 整理 实体类 Ctor 有构造函数的映射处理;#164 [wiki](https://github.com/2881099/FreeSql/wiki/%e8%bf%94%e5%9b%9e%e6%95%b0%e6%8d%ae#dto-%E6%98%A0%E5%B0%84%E6%9F%A5%E8%AF%A2) - 优化 实体属性,支持 protected set 属性;#164
This commit is contained in:
parent
738eeb81a8
commit
d5ed1c8a30
@ -15,7 +15,7 @@ namespace FreeSql
|
|||||||
DbContext ctx = null;
|
DbContext ctx = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var ctor = dbContextType.GetConstructors().FirstOrDefault();
|
var ctor = dbContextType. GetConstructors().FirstOrDefault();
|
||||||
var ctorParams = ctor.GetParameters().Select(a => sp.GetService(a.ParameterType)).ToArray();
|
var ctorParams = ctor.GetParameters().Select(a => sp.GetService(a.ParameterType)).ToArray();
|
||||||
ctx = Activator.CreateInstance(dbContextType, ctorParams) as DbContext;
|
ctx = Activator.CreateInstance(dbContextType, ctorParams) as DbContext;
|
||||||
}
|
}
|
||||||
|
@ -110,13 +110,6 @@
|
|||||||
清空状态数据
|
清空状态数据
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:FreeSql.DbSet`1.RemoveAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
|
|
||||||
<summary>
|
|
||||||
根据 lambda 条件删除数据
|
|
||||||
</summary>
|
|
||||||
<param name="predicate"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:FreeSql.DbSet`1.Add(`0)">
|
<member name="M:FreeSql.DbSet`1.Add(`0)">
|
||||||
<summary>
|
<summary>
|
||||||
添加
|
添加
|
||||||
|
@ -1056,6 +1056,23 @@ WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title`
|
|||||||
a.Id,
|
a.Id,
|
||||||
a.Clicks
|
a.Clicks
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2
|
||||||
|
FROM (SELECT * from (SELECT a.`Id` Id, a.`Clicks` Clicks
|
||||||
|
FROM `tb_topic_1` a) ftb
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT * from (SELECT a.`Id` Id, a.`Clicks` Clicks
|
||||||
|
FROM `tb_topic_2` a) ftb) a
|
||||||
|
limit 0,20", select
|
||||||
|
.AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null)
|
||||||
|
.Page(1, 20)
|
||||||
|
.ToSql(a => new
|
||||||
|
{
|
||||||
|
a.Id,
|
||||||
|
a.Clicks
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TestInclude_OneToManyModel1
|
public class TestInclude_OneToManyModel1
|
||||||
|
@ -17,11 +17,7 @@ namespace FreeSql.Tests.MySql
|
|||||||
var sql = g.mysql.CodeFirst.GetComparisonDDLStatements<测试中文表2>();
|
var sql = g.mysql.CodeFirst.GetComparisonDDLStatements<测试中文表2>();
|
||||||
g.mysql.CodeFirst.SyncStructure<测试中文表2>();
|
g.mysql.CodeFirst.SyncStructure<测试中文表2>();
|
||||||
|
|
||||||
var item = new 测试中文表2
|
var item = 测试中文表2.Create("测试标题", DateTime.Now);
|
||||||
{
|
|
||||||
标题 = "测试标题",
|
|
||||||
创建时间 = DateTime.Now
|
|
||||||
};
|
|
||||||
Assert.Equal(1, g.mysql.Insert<测试中文表2>().AppendData(item).ExecuteAffrows());
|
Assert.Equal(1, g.mysql.Insert<测试中文表2>().AppendData(item).ExecuteAffrows());
|
||||||
Assert.NotEqual(Guid.Empty, item.编号);
|
Assert.NotEqual(Guid.Empty, item.编号);
|
||||||
var item2 = g.mysql.Select<测试中文表2>().Where(a => a.编号 == item.编号).First();
|
var item2 = g.mysql.Select<测试中文表2>().Where(a => a.编号 == item.编号).First();
|
||||||
@ -32,12 +28,17 @@ namespace FreeSql.Tests.MySql
|
|||||||
class 测试中文表2
|
class 测试中文表2
|
||||||
{
|
{
|
||||||
[Column(IsPrimary = true)]
|
[Column(IsPrimary = true)]
|
||||||
public Guid 编号 { get; set; }
|
public Guid 编号 { get; protected set; }
|
||||||
|
|
||||||
public string 标题 { get; set; }
|
public string 标题 { get; protected set; }
|
||||||
|
|
||||||
[Column(ServerTime = DateTimeKind.Local)]
|
[Column(ServerTime = DateTimeKind.Local)]
|
||||||
public DateTime 创建时间 { get; set; }
|
public DateTime 创建时间 { get; protected set; }
|
||||||
|
|
||||||
|
public static 测试中文表2 Create(string title, DateTime ctm)
|
||||||
|
{
|
||||||
|
return new 测试中文表2 { 标题 = title, 创建时间 = ctm };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -47,21 +47,35 @@ public static partial class FreeSqlGlobalExtensions
|
|||||||
public static bool IsArrayOrList(this Type that) => that == null ? false : (that.IsArray || typeof(IList).IsAssignableFrom(that));
|
public static bool IsArrayOrList(this Type that) => that == null ? false : (that.IsArray || typeof(IList).IsAssignableFrom(that));
|
||||||
public static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GetGenericArguments().First() : that;
|
public static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GetGenericArguments().First() : that;
|
||||||
internal static string NotNullAndConcat(this string that, params object[] args) => string.IsNullOrEmpty(that) ? null : string.Concat(new object[] { that }.Concat(args));
|
internal static string NotNullAndConcat(this string that, params object[] args) => string.IsNullOrEmpty(that) ? null : string.Concat(new object[] { that }.Concat(args));
|
||||||
static ConcurrentDictionary<Type, ParameterInfo[]> _dicGetDefaultValueFirstConstructorsParameters = new ConcurrentDictionary<Type, ParameterInfo[]>();
|
|
||||||
public static object CreateInstanceGetDefaultValue(this Type that)
|
public static object CreateInstanceGetDefaultValue(this Type that)
|
||||||
{
|
{
|
||||||
if (that == null) return null;
|
if (that == null) return null;
|
||||||
if (that == typeof(string)) return default(string);
|
if (that == typeof(string)) return default(string);
|
||||||
if (that.IsArray) return Array.CreateInstance(that, 0);
|
if (that.IsArray) return Array.CreateInstance(that, 0);
|
||||||
var ctorParms = _dicGetDefaultValueFirstConstructorsParameters.GetOrAdd(that, tp => tp.GetConstructors().FirstOrDefault()?.GetParameters());
|
var ctorParms = that.InternalGetTypeConstructor0OrFirst(false)?.GetParameters();
|
||||||
if (ctorParms == null || ctorParms.Any() == false) return Activator.CreateInstance(that, null);
|
if (ctorParms == null || ctorParms.Any() == false) return Activator.CreateInstance(that, null);
|
||||||
return Activator.CreateInstance(that, ctorParms.Select(a => Activator.CreateInstance(a.ParameterType, null)).ToArray());
|
return Activator.CreateInstance(that, ctorParms.Select(a => Activator.CreateInstance(a.ParameterType, null)).ToArray());
|
||||||
}
|
}
|
||||||
|
internal static NewExpression InternalNewExpression(this Type that)
|
||||||
|
{
|
||||||
|
var ctor = that.InternalGetTypeConstructor0OrFirst();
|
||||||
|
return Expression.New(ctor, ctor.GetParameters().Select(a => Expression.Constant(a.ParameterType.CreateInstanceGetDefaultValue(), a.ParameterType)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ConcurrentDictionary<Type, ConstructorInfo> _dicInternalGetTypeConstructor0OrFirst = new ConcurrentDictionary<Type, ConstructorInfo>();
|
||||||
|
internal static ConstructorInfo InternalGetTypeConstructor0OrFirst(this Type that, bool isThrow = true)
|
||||||
|
{
|
||||||
|
var ret = _dicInternalGetTypeConstructor0OrFirst.GetOrAdd(that, tp =>
|
||||||
|
tp.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null) ??
|
||||||
|
tp.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault());
|
||||||
|
if (ret == null && isThrow) throw new ArgumentException($"{that.FullName} 类型无方法访问构造函数");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static ConcurrentDictionary<Type, Dictionary<string, PropertyInfo>> _dicGetPropertiesDictIgnoreCase = new ConcurrentDictionary<Type, Dictionary<string, PropertyInfo>>();
|
static ConcurrentDictionary<Type, Dictionary<string, PropertyInfo>> _dicGetPropertiesDictIgnoreCase = new ConcurrentDictionary<Type, Dictionary<string, PropertyInfo>>();
|
||||||
public static Dictionary<string, PropertyInfo> GetPropertiesDictIgnoreCase(this Type that) => that == null ? null : _dicGetPropertiesDictIgnoreCase.GetOrAdd(that, tp =>
|
public static Dictionary<string, PropertyInfo> GetPropertiesDictIgnoreCase(this Type that) => that == null ? null : _dicGetPropertiesDictIgnoreCase.GetOrAdd(that, tp =>
|
||||||
{
|
{
|
||||||
var props = that.GetProperties();
|
var props = that.GetProperties().GroupBy(p => p.DeclaringType).Reverse().SelectMany(p => p); //将基类的属性位置放在前面 #164
|
||||||
var dict = new Dictionary<string, PropertyInfo>(StringComparer.CurrentCultureIgnoreCase);
|
var dict = new Dictionary<string, PropertyInfo>(StringComparer.CurrentCultureIgnoreCase);
|
||||||
foreach (var prop in props)
|
foreach (var prop in props)
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,8 @@ namespace FreeSql.Internal
|
|||||||
var constExpValue = constExp.Value?.ToString() ?? "NULL";
|
var constExpValue = constExp.Value?.ToString() ?? "NULL";
|
||||||
if (constExpValue == string.Empty) constExpValue = _common.FormatSql("{0}", "");
|
if (constExpValue == string.Empty) constExpValue = _common.FormatSql("{0}", "");
|
||||||
parent.DbField = constExpValue;
|
parent.DbField = constExpValue;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
parent.DbField = _common.FormatSql("{0}", constExp?.Value);
|
parent.DbField = _common.FormatSql("{0}", constExp?.Value);
|
||||||
field.Append(", ").Append(parent.DbField);
|
field.Append(", ").Append(parent.DbField);
|
||||||
if (index >= 0) field.Append(" as").Append(++index);
|
if (index >= 0) field.Append(" as").Append(++index);
|
||||||
@ -82,8 +83,8 @@ namespace FreeSql.Internal
|
|||||||
var map = new List<SelectColumnInfo>();
|
var map = new List<SelectColumnInfo>();
|
||||||
ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, getSelectGroupingMapString);
|
ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, getSelectGroupingMapString);
|
||||||
var tb = parent.Table = map.First().Table.Table;
|
var tb = parent.Table = map.First().Table.Table;
|
||||||
parent.Consturctor = tb.Type.GetConstructor(new Type[0]);
|
parent.CsType = tb.Type;
|
||||||
parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
|
parent.Consturctor = tb.Type.InternalGetTypeConstructor0OrFirst();
|
||||||
parent.IsEntity = true;
|
parent.IsEntity = true;
|
||||||
for (var idx = 0; idx < map.Count; idx++)
|
for (var idx = 0; idx < map.Count; idx++)
|
||||||
{
|
{
|
||||||
@ -113,10 +114,25 @@ namespace FreeSql.Internal
|
|||||||
return false;
|
return false;
|
||||||
case ExpressionType.MemberInit:
|
case ExpressionType.MemberInit:
|
||||||
var initExp = exp as MemberInitExpression;
|
var initExp = exp as MemberInitExpression;
|
||||||
parent.Consturctor = initExp.NewExpression.Type.GetConstructors()[0];
|
parent.CsType = initExp.Type;
|
||||||
parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
|
parent.Consturctor = initExp.NewExpression.Constructor;
|
||||||
|
if (initExp.NewExpression?.Arguments.Count > 0)
|
||||||
if (isAllDtoMap && _tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type)
|
{
|
||||||
|
//处理构造参数
|
||||||
|
for (var a = 0; a < initExp.NewExpression.Arguments.Count; a++)
|
||||||
|
{
|
||||||
|
var child = new ReadAnonymousTypeInfo
|
||||||
|
{
|
||||||
|
Property = null,
|
||||||
|
CsName = initExp.NewExpression.Members[a].Name,
|
||||||
|
CsType = initExp.NewExpression.Arguments[a].Type,
|
||||||
|
MapType = initExp.NewExpression.Arguments[a].Type
|
||||||
|
};
|
||||||
|
parent.Childs.Add(child);
|
||||||
|
ReadAnonymousField(_tables, field, child, ref index, initExp.NewExpression.Arguments[a], getSelectGroupingMapString, whereCascadeExpression, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (isAllDtoMap && _tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type)
|
||||||
{
|
{
|
||||||
//dto 映射
|
//dto 映射
|
||||||
var dtoProps = initExp.NewExpression.Type.GetPropertiesDictIgnoreCase().Values;
|
var dtoProps = initExp.NewExpression.Type.GetPropertiesDictIgnoreCase().Values;
|
||||||
@ -124,26 +140,26 @@ namespace FreeSql.Internal
|
|||||||
{
|
{
|
||||||
foreach (var dtTb in _tables)
|
foreach (var dtTb in _tables)
|
||||||
{
|
{
|
||||||
if (dtTb.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol))
|
if (dtTb.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol) == false) continue;
|
||||||
|
if (trydtocol.Attribute.IsIgnore == true) continue;
|
||||||
|
|
||||||
|
var child = new ReadAnonymousTypeInfo
|
||||||
{
|
{
|
||||||
var child = new ReadAnonymousTypeInfo
|
Property = dtoProp,
|
||||||
{
|
CsName = dtoProp.Name,
|
||||||
Property = dtoProp,
|
CsType = trydtocol.CsType, // dtoProp.PropertyType,
|
||||||
CsName = dtoProp.Name,
|
MapType = trydtocol.Attribute.MapType
|
||||||
CsType = trydtocol.CsType, // dtoProp.PropertyType,
|
};
|
||||||
MapType = trydtocol.Attribute.MapType
|
parent.Childs.Add(child);
|
||||||
};
|
if (dtTb.Parameter != null)
|
||||||
parent.Childs.Add(child);
|
ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap);
|
||||||
if (dtTb.Parameter != null)
|
else
|
||||||
ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap);
|
{
|
||||||
else
|
child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}";
|
||||||
{
|
field.Append(", ").Append(child.DbField);
|
||||||
child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}";
|
if (index >= 0) field.Append(" as").Append(++index);
|
||||||
field.Append(", ").Append(child.DbField);
|
|
||||||
if (index >= 0) field.Append(" as").Append(++index);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,15 +185,27 @@ namespace FreeSql.Internal
|
|||||||
return true;
|
return true;
|
||||||
case ExpressionType.New:
|
case ExpressionType.New:
|
||||||
var newExp = exp as NewExpression;
|
var newExp = exp as NewExpression;
|
||||||
parent.Consturctor = newExp.Type.GetConstructors()[0];
|
parent.CsType = newExp.Type;
|
||||||
parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Arguments;
|
parent.Consturctor = newExp.Constructor;
|
||||||
if (newExp.Members?.Count > 0)
|
if (newExp.Arguments?.Count > 0 &&
|
||||||
|
(
|
||||||
|
newExp.Type.IsAnonymousType() ||
|
||||||
|
newExp.Arguments.Any(a =>
|
||||||
|
{
|
||||||
|
if (a.NodeType != ExpressionType.Constant) return true;
|
||||||
|
var constVal = (a as ConstantExpression)?.Value;
|
||||||
|
if (constVal == null) return true;
|
||||||
|
if (object.Equals(constVal, a.Type.CreateInstanceGetDefaultValue()) == false) return true;
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
))
|
||||||
{
|
{
|
||||||
for (var a = 0; a < newExp.Members.Count; a++)
|
//处理构造参数
|
||||||
|
for (var a = 0; a < newExp.Arguments.Count; a++)
|
||||||
{
|
{
|
||||||
var child = new ReadAnonymousTypeInfo
|
var child = new ReadAnonymousTypeInfo
|
||||||
{
|
{
|
||||||
Property = newExp.Type.GetProperty(newExp.Members[a].Name, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance),
|
Property = null,
|
||||||
CsName = newExp.Members[a].Name,
|
CsName = newExp.Members[a].Name,
|
||||||
CsType = newExp.Arguments[a].Type,
|
CsType = newExp.Arguments[a].Type,
|
||||||
MapType = newExp.Arguments[a].Type
|
MapType = newExp.Arguments[a].Type
|
||||||
@ -188,37 +216,37 @@ namespace FreeSql.Internal
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
parent.IsDefaultCtor = true;
|
||||||
//dto 映射
|
//dto 映射
|
||||||
parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
|
|
||||||
var dtoProps2 = newExp.Type.GetPropertiesDictIgnoreCase().Values;
|
var dtoProps2 = newExp.Type.GetPropertiesDictIgnoreCase().Values;
|
||||||
foreach (var dtoProp in dtoProps2)
|
foreach (var dtoProp in dtoProps2)
|
||||||
{
|
{
|
||||||
foreach (var dtTb in _tables)
|
foreach (var dtTb in _tables)
|
||||||
{
|
{
|
||||||
if (dtTb.Table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trydtocol))
|
if (dtTb.Table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trydtocol) == false) continue;
|
||||||
|
if (trydtocol.Attribute.IsIgnore == true) continue;
|
||||||
|
|
||||||
|
var child = new ReadAnonymousTypeInfo
|
||||||
{
|
{
|
||||||
var child = new ReadAnonymousTypeInfo
|
Property = dtoProp,
|
||||||
{
|
CsName = dtoProp.Name,
|
||||||
Property = dtoProp,
|
CsType = trydtocol.CsType, //dtoProp.PropertyType,
|
||||||
CsName = dtoProp.Name,
|
MapType = trydtocol.Attribute.MapType
|
||||||
CsType = trydtocol.CsType, //dtoProp.PropertyType,
|
};
|
||||||
MapType = trydtocol.Attribute.MapType
|
parent.Childs.Add(child);
|
||||||
};
|
if (dtTb.Parameter != null)
|
||||||
parent.Childs.Add(child);
|
ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap);
|
||||||
if (dtTb.Parameter != null)
|
else
|
||||||
ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap);
|
{
|
||||||
else
|
child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}";
|
||||||
{
|
field.Append(", ").Append(child.DbField);
|
||||||
child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}";
|
if (index >= 0) field.Append(" as").Append(++index);
|
||||||
field.Append(", ").Append(child.DbField);
|
|
||||||
if (index >= 0) field.Append(" as").Append(++index);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (parent.Childs.Any() == false) throw new Exception($"映射异常:{newExp.Type.Name} 没有一个属性名相同");
|
|
||||||
}
|
}
|
||||||
|
if (parent.Childs.Any() == false) throw new Exception($"映射异常:{newExp.Type.Name} 没有一个属性名相同");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
parent.DbField = $"({ExpressionLambdaToSql(exp, getTSC())})";
|
parent.DbField = $"({ExpressionLambdaToSql(exp, getTSC())})";
|
||||||
@ -247,33 +275,30 @@ namespace FreeSql.Internal
|
|||||||
objval = Utils.GetDataReaderValue(parent.Property.PropertyType, objval);
|
objval = Utils.GetDataReaderValue(parent.Property.PropertyType, objval);
|
||||||
return objval;
|
return objval;
|
||||||
}
|
}
|
||||||
switch (parent.ConsturctorType)
|
var ctorParmsLength = 0;
|
||||||
|
object ret;
|
||||||
|
if (parent.IsDefaultCtor || parent.IsEntity || (ctorParmsLength = parent.Consturctor.GetParameters()?.Length ?? 0) == 0)
|
||||||
|
ret = parent.CsType?.CreateInstanceGetDefaultValue() ?? parent.Consturctor.Invoke(null);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
case ReadAnonymousTypeInfoConsturctorType.Arguments:
|
var ctorParms = new object[ctorParmsLength];
|
||||||
var args = new object[parent.Childs.Count];
|
for (var c = 0; c < ctorParmsLength; c++)
|
||||||
for (var a = 0; a < parent.Childs.Count; a++)
|
ctorParms[c] = ReadAnonymous(parent.Childs[c], dr, ref index, notRead, null);
|
||||||
{
|
ret = parent.Consturctor.Invoke(ctorParms);
|
||||||
var objval = ReadAnonymous(parent.Childs[a], dr, ref index, notRead, null);
|
|
||||||
if (notRead == false)
|
|
||||||
args[a] = objval;
|
|
||||||
}
|
|
||||||
return parent.Consturctor.Invoke(args);
|
|
||||||
case ReadAnonymousTypeInfoConsturctorType.Properties:
|
|
||||||
var ret = parent.Consturctor.Invoke(null);
|
|
||||||
var isnull = notRead;
|
|
||||||
for (var b = 0; b < parent.Childs.Count; b++)
|
|
||||||
{
|
|
||||||
var prop = parent.Childs[b].Property;
|
|
||||||
var dbval = parent.IsEntity ? new ReadAnonymousDbValueRef() : null;
|
|
||||||
var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead, dbval);
|
|
||||||
if (isnull == false && parent.IsEntity && dbval.DbValue == null && parent.Table != null && parent.Table.ColumnsByCs.TryGetValue(parent.Childs[b].CsName, out var trycol) && trycol.Attribute.IsPrimary)
|
|
||||||
isnull = true;
|
|
||||||
if (isnull == false && prop.CanWrite)
|
|
||||||
prop.SetValue(ret, objval, null);
|
|
||||||
}
|
|
||||||
return isnull ? null : ret;
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
|
var isnull = notRead;
|
||||||
|
for (var b = ctorParmsLength; b < parent.Childs.Count; b++)
|
||||||
|
{
|
||||||
|
var prop = parent.Childs[b].Property;
|
||||||
|
var dbval = parent.IsEntity ? new ReadAnonymousDbValueRef() : null;
|
||||||
|
var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead, dbval);
|
||||||
|
if (isnull == false && parent.IsEntity && dbval.DbValue == null && parent.Table != null && parent.Table.ColumnsByCs.TryGetValue(parent.Childs[b].CsName, out var trycol) && trycol.Attribute.IsPrimary)
|
||||||
|
isnull = true;
|
||||||
|
if (isnull == false && prop.CanWrite)
|
||||||
|
prop.SetValue(ret, objval, null);
|
||||||
|
}
|
||||||
|
return isnull ? null : ret;
|
||||||
}
|
}
|
||||||
public class ReadAnonymousDbValueRef
|
public class ReadAnonymousDbValueRef
|
||||||
{
|
{
|
||||||
|
@ -546,7 +546,6 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
_commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null, _whereCascadeExpression, true);
|
_commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null, _whereCascadeExpression, true);
|
||||||
return (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null);
|
return (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null);
|
||||||
}
|
}
|
||||||
static ConcurrentDictionary<Type, ConstructorInfo> _dicConstructor = new ConcurrentDictionary<Type, ConstructorInfo>();
|
|
||||||
static ConcurrentDictionary<string, GetAllFieldExpressionTreeInfo> _dicGetAllFieldExpressionTree = new ConcurrentDictionary<string, GetAllFieldExpressionTreeInfo>();
|
static ConcurrentDictionary<string, GetAllFieldExpressionTreeInfo> _dicGetAllFieldExpressionTree = new ConcurrentDictionary<string, GetAllFieldExpressionTreeInfo>();
|
||||||
public class GetAllFieldExpressionTreeInfo
|
public class GetAllFieldExpressionTreeInfo
|
||||||
{
|
{
|
||||||
@ -568,9 +567,8 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue);
|
var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue);
|
||||||
var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex);
|
var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex);
|
||||||
var blockExp = new List<Expression>();
|
var blockExp = new List<Expression>();
|
||||||
var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First();
|
|
||||||
blockExp.AddRange(new Expression[] {
|
blockExp.AddRange(new Expression[] {
|
||||||
Expression.Assign(retExp, Expression.New(ctor, ctor.GetParameters().Select(a => Expression.Default(a.ParameterType)))),
|
Expression.Assign(retExp, type.InternalNewExpression()),
|
||||||
Expression.Assign(dataIndexExp, Expression.Constant(0))
|
Expression.Assign(dataIndexExp, Expression.Constant(0))
|
||||||
});
|
});
|
||||||
//typeof(Topic).GetMethod("get_Type").IsVirtual
|
//typeof(Topic).GetMethod("get_Type").IsVirtual
|
||||||
@ -711,9 +709,8 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue);
|
var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue);
|
||||||
var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex);
|
var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex);
|
||||||
var blockExp = new List<Expression>();
|
var blockExp = new List<Expression>();
|
||||||
var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First();
|
|
||||||
blockExp.AddRange(new Expression[] {
|
blockExp.AddRange(new Expression[] {
|
||||||
Expression.Assign(retExp, Expression.New(ctor, ctor.GetParameters().Select(a => Expression.Default(a.ParameterType)))),
|
Expression.Assign(retExp, type.InternalNewExpression()),
|
||||||
Expression.Assign(dataIndexExp, Expression.Constant(0))
|
Expression.Assign(dataIndexExp, Expression.Constant(0))
|
||||||
});
|
});
|
||||||
//typeof(Topic).GetMethod("get_Type").IsVirtual
|
//typeof(Topic).GetMethod("get_Type").IsVirtual
|
||||||
@ -762,7 +759,7 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//只读到二级属性
|
//只读到二级属性
|
||||||
var propGetSetMethod = prop.GetSetMethod();
|
var propGetSetMethod = prop.GetSetMethod(true);
|
||||||
Expression readExpAssign = null; //加速缓存
|
Expression readExpAssign = null; //加速缓存
|
||||||
if (prop.PropertyType.IsArray) readExpAssign = Expression.New(Utils.RowInfo.Constructor,
|
if (prop.PropertyType.IsArray) readExpAssign = Expression.New(Utils.RowInfo.Constructor,
|
||||||
Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp)),
|
Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp)),
|
||||||
@ -836,9 +833,9 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
protected (ReadAnonymousTypeInfo map, string field) GetAllFieldReflection()
|
protected (ReadAnonymousTypeInfo map, string field) GetAllFieldReflection()
|
||||||
{
|
{
|
||||||
var tb1 = _tables.First().Table;
|
var tb1 = _tables.First().Table;
|
||||||
var type = tb1.Type;
|
var type = tb1.TypeLazy ?? tb1.Type;
|
||||||
var constructor = _dicConstructor.GetOrAdd(type, s => type.GetConstructor(new Type[0]));
|
var constructor = type.InternalGetTypeConstructor0OrFirst();
|
||||||
var map = new ReadAnonymousTypeInfo { Consturctor = constructor, ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties };
|
var map = new ReadAnonymousTypeInfo { CsType = type, Consturctor = constructor, IsEntity = true };
|
||||||
|
|
||||||
var field = new StringBuilder();
|
var field = new StringBuilder();
|
||||||
var dicfield = new Dictionary<string, bool>();
|
var dicfield = new Dictionary<string, bool>();
|
||||||
@ -862,8 +859,9 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
var tb2 = _tables.Where(a => a.Table.Type == p.PropertyType && a.Alias.Contains(p.Name)).FirstOrDefault();
|
var tb2 = _tables.Where(a => a.Table.Type == p.PropertyType && a.Alias.Contains(p.Name)).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 && ps.Where(pw => pw.Value.PropertyType == p.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == p.PropertyType).FirstOrDefault();
|
||||||
if (tb2 == null) continue;
|
if (tb2 == null) continue;
|
||||||
child.Consturctor = tb2.Table.Type.GetConstructor(new Type[0]);
|
child.CsType = (tb2.Table.TypeLazy ?? tb2.Table.Type);
|
||||||
child.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
|
child.Consturctor = child.CsType.InternalGetTypeConstructor0OrFirst();
|
||||||
|
child.IsEntity = true;
|
||||||
foreach (var col2 in tb2.Table.Columns.Values)
|
foreach (var col2 in tb2.Table.Columns.Values)
|
||||||
{
|
{
|
||||||
if (index > 0) field.Append(", ");
|
if (index > 0) field.Append(", ");
|
||||||
|
@ -101,8 +101,8 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
List<TDto> ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>).ToList(GetToListDtoSelector<TDto>());
|
List<TDto> ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>).ToList(GetToListDtoSelector<TDto>());
|
||||||
Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TDto>> GetToListDtoSelector<TDto>()
|
Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TDto>> GetToListDtoSelector<TDto>()
|
||||||
{
|
{
|
||||||
var ctor = typeof(TDto).GetConstructor(new Type[0]);
|
return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TDto>>(
|
||||||
return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TDto>>(Expression.New(ctor),
|
typeof(TDto).InternalNewExpression(),
|
||||||
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
||||||
Expression.Parameter(typeof(T2), "b"),
|
Expression.Parameter(typeof(T2), "b"),
|
||||||
Expression.Parameter(typeof(T3), "c"),
|
Expression.Parameter(typeof(T3), "c"),
|
||||||
|
@ -172,8 +172,8 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
public List<TDto> ToList<TDto>() => ToList(GetToListDtoSelector<TDto>());
|
public List<TDto> ToList<TDto>() => ToList(GetToListDtoSelector<TDto>());
|
||||||
Expression<Func<T1, TDto>> GetToListDtoSelector<TDto>()
|
Expression<Func<T1, TDto>> GetToListDtoSelector<TDto>()
|
||||||
{
|
{
|
||||||
var ctor = typeof(TDto).GetConstructor(new Type[0]);
|
return Expression.Lambda<Func<T1, TDto>>(
|
||||||
return Expression.Lambda<Func<T1, TDto>>(Expression.New(ctor),
|
typeof(TDto).InternalNewExpression(),
|
||||||
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"));
|
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -884,8 +884,9 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
{
|
{
|
||||||
var field = new StringBuilder();
|
var field = new StringBuilder();
|
||||||
var read = new ReadAnonymousTypeInfo();
|
var read = new ReadAnonymousTypeInfo();
|
||||||
read.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
|
read.CsType = (tbrefMid.TypeLazy ?? tbrefMid.Type);
|
||||||
read.Consturctor = (tbrefMid.TypeLazy ?? tbrefMid.Type).GetConstructor(new Type[0]);
|
read.Consturctor = read.CsType.InternalGetTypeConstructor0OrFirst();
|
||||||
|
read.IsEntity = true;
|
||||||
read.Table = tbrefMid;
|
read.Table = tbrefMid;
|
||||||
foreach (var col in tbrefMid.Columns.Values)
|
foreach (var col in tbrefMid.Columns.Values)
|
||||||
{
|
{
|
||||||
|
@ -86,8 +86,8 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
List<TDto> ISelect<T1, T2>.ToList<TDto>() => (this as ISelect<T1, T2>).ToList(GetToListDtoSelector<TDto>());
|
List<TDto> ISelect<T1, T2>.ToList<TDto>() => (this as ISelect<T1, T2>).ToList(GetToListDtoSelector<TDto>());
|
||||||
Expression<Func<T1, T2, TDto>> GetToListDtoSelector<TDto>()
|
Expression<Func<T1, T2, TDto>> GetToListDtoSelector<TDto>()
|
||||||
{
|
{
|
||||||
var ctor = typeof(TDto).GetConstructor(new Type[0]);
|
return Expression.Lambda<Func<T1, T2, TDto>>(
|
||||||
return Expression.Lambda<Func<T1, T2, TDto>>(Expression.New(ctor),
|
typeof(TDto).InternalNewExpression(),
|
||||||
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
||||||
Expression.Parameter(typeof(T2), "b"));
|
Expression.Parameter(typeof(T2), "b"));
|
||||||
}
|
}
|
||||||
|
@ -88,8 +88,8 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
List<TDto> ISelect<T1, T2, T3>.ToList<TDto>() => (this as ISelect<T1, T2, T3>).ToList(GetToListDtoSelector<TDto>());
|
List<TDto> ISelect<T1, T2, T3>.ToList<TDto>() => (this as ISelect<T1, T2, T3>).ToList(GetToListDtoSelector<TDto>());
|
||||||
Expression<Func<T1, T2, T3, TDto>> GetToListDtoSelector<TDto>()
|
Expression<Func<T1, T2, T3, TDto>> GetToListDtoSelector<TDto>()
|
||||||
{
|
{
|
||||||
var ctor = typeof(TDto).GetConstructor(new Type[0]);
|
return Expression.Lambda<Func<T1, T2, T3, TDto>>(
|
||||||
return Expression.Lambda<Func<T1, T2, T3, TDto>>(Expression.New(ctor),
|
typeof(TDto).InternalNewExpression(),
|
||||||
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
||||||
Expression.Parameter(typeof(T2), "b"),
|
Expression.Parameter(typeof(T2), "b"),
|
||||||
Expression.Parameter(typeof(T3), "c"));
|
Expression.Parameter(typeof(T3), "c"));
|
||||||
|
@ -90,8 +90,8 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
List<TDto> ISelect<T1, T2, T3, T4>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4>).ToList(GetToListDtoSelector<TDto>());
|
List<TDto> ISelect<T1, T2, T3, T4>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4>).ToList(GetToListDtoSelector<TDto>());
|
||||||
Expression<Func<T1, T2, T3, T4, TDto>> GetToListDtoSelector<TDto>()
|
Expression<Func<T1, T2, T3, T4, TDto>> GetToListDtoSelector<TDto>()
|
||||||
{
|
{
|
||||||
var ctor = typeof(TDto).GetConstructor(new Type[0]);
|
return Expression.Lambda<Func<T1, T2, T3, T4, TDto>>(
|
||||||
return Expression.Lambda<Func<T1, T2, T3, T4, TDto>>(Expression.New(ctor),
|
typeof(TDto).InternalNewExpression(),
|
||||||
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
||||||
Expression.Parameter(typeof(T2), "b"),
|
Expression.Parameter(typeof(T2), "b"),
|
||||||
Expression.Parameter(typeof(T3), "c"),
|
Expression.Parameter(typeof(T3), "c"),
|
||||||
|
@ -92,8 +92,8 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
List<TDto> ISelect<T1, T2, T3, T4, T5>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5>).ToList(GetToListDtoSelector<TDto>());
|
List<TDto> ISelect<T1, T2, T3, T4, T5>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5>).ToList(GetToListDtoSelector<TDto>());
|
||||||
Expression<Func<T1, T2, T3, T4, T5, TDto>> GetToListDtoSelector<TDto>()
|
Expression<Func<T1, T2, T3, T4, T5, TDto>> GetToListDtoSelector<TDto>()
|
||||||
{
|
{
|
||||||
var ctor = typeof(TDto).GetConstructor(new Type[0]);
|
return Expression.Lambda<Func<T1, T2, T3, T4, T5, TDto>>(
|
||||||
return Expression.Lambda<Func<T1, T2, T3, T4, T5, TDto>>(Expression.New(ctor),
|
typeof(TDto).InternalNewExpression(),
|
||||||
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
||||||
Expression.Parameter(typeof(T2), "b"),
|
Expression.Parameter(typeof(T2), "b"),
|
||||||
Expression.Parameter(typeof(T3), "c"),
|
Expression.Parameter(typeof(T3), "c"),
|
||||||
|
@ -94,8 +94,8 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
List<TDto> ISelect<T1, T2, T3, T4, T5, T6>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5, T6>).ToList(GetToListDtoSelector<TDto>());
|
List<TDto> ISelect<T1, T2, T3, T4, T5, T6>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5, T6>).ToList(GetToListDtoSelector<TDto>());
|
||||||
Expression<Func<T1, T2, T3, T4, T5, T6, TDto>> GetToListDtoSelector<TDto>()
|
Expression<Func<T1, T2, T3, T4, T5, T6, TDto>> GetToListDtoSelector<TDto>()
|
||||||
{
|
{
|
||||||
var ctor = typeof(TDto).GetConstructor(new Type[0]);
|
return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, TDto>>(
|
||||||
return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, TDto>>(Expression.New(ctor),
|
typeof(TDto).InternalNewExpression(),
|
||||||
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
||||||
Expression.Parameter(typeof(T2), "b"),
|
Expression.Parameter(typeof(T2), "b"),
|
||||||
Expression.Parameter(typeof(T3), "c"),
|
Expression.Parameter(typeof(T3), "c"),
|
||||||
|
@ -96,8 +96,8 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
List<TDto> ISelect<T1, T2, T3, T4, T5, T6, T7>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5, T6, T7>).ToList(GetToListDtoSelector<TDto>());
|
List<TDto> ISelect<T1, T2, T3, T4, T5, T6, T7>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5, T6, T7>).ToList(GetToListDtoSelector<TDto>());
|
||||||
Expression<Func<T1, T2, T3, T4, T5, T6, T7, TDto>> GetToListDtoSelector<TDto>()
|
Expression<Func<T1, T2, T3, T4, T5, T6, T7, TDto>> GetToListDtoSelector<TDto>()
|
||||||
{
|
{
|
||||||
var ctor = typeof(TDto).GetConstructor(new Type[0]);
|
return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, TDto>>(
|
||||||
return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, TDto>>(Expression.New(ctor),
|
typeof(TDto).InternalNewExpression(),
|
||||||
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
||||||
Expression.Parameter(typeof(T2), "b"),
|
Expression.Parameter(typeof(T2), "b"),
|
||||||
Expression.Parameter(typeof(T3), "c"),
|
Expression.Parameter(typeof(T3), "c"),
|
||||||
|
@ -99,8 +99,8 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
|
|
||||||
Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TDto>> GetToListDtoSelector<TDto>()
|
Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TDto>> GetToListDtoSelector<TDto>()
|
||||||
{
|
{
|
||||||
var ctor = typeof(TDto).GetConstructor(new Type[0]);
|
return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, TDto>>(
|
||||||
return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, TDto>>(Expression.New(ctor),
|
typeof(TDto).InternalNewExpression(),
|
||||||
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
||||||
Expression.Parameter(typeof(T2), "b"),
|
Expression.Parameter(typeof(T2), "b"),
|
||||||
Expression.Parameter(typeof(T3), "c"),
|
Expression.Parameter(typeof(T3), "c"),
|
||||||
|
@ -99,8 +99,8 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
List<TDto> ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>).ToList(GetToListDtoSelector<TDto>());
|
List<TDto> ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>).ToList(GetToListDtoSelector<TDto>());
|
||||||
Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TDto>> GetToListDtoSelector<TDto>()
|
Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TDto>> GetToListDtoSelector<TDto>()
|
||||||
{
|
{
|
||||||
var ctor = typeof(TDto).GetConstructor(new Type[0]);
|
return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TDto>>(
|
||||||
return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TDto>>(Expression.New(ctor),
|
typeof(TDto).InternalNewExpression(),
|
||||||
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
|
||||||
Expression.Parameter(typeof(T2), "b"),
|
Expression.Parameter(typeof(T2), "b"),
|
||||||
Expression.Parameter(typeof(T3), "c"),
|
Expression.Parameter(typeof(T3), "c"),
|
||||||
|
@ -13,10 +13,9 @@ namespace FreeSql.Internal.Model
|
|||||||
public Type MapType { get; set; }
|
public Type MapType { get; set; }
|
||||||
public string DbField { get; set; }
|
public string DbField { get; set; }
|
||||||
public ConstructorInfo Consturctor { get; set; }
|
public ConstructorInfo Consturctor { get; set; }
|
||||||
public ReadAnonymousTypeInfoConsturctorType ConsturctorType { get; set; }
|
|
||||||
public List<ReadAnonymousTypeInfo> Childs = new List<ReadAnonymousTypeInfo>();
|
public List<ReadAnonymousTypeInfo> Childs = new List<ReadAnonymousTypeInfo>();
|
||||||
public TableInfo Table { get; set; }
|
public TableInfo Table { get; set; }
|
||||||
public bool IsEntity { get; set; }
|
public bool IsEntity { get; set; }
|
||||||
|
public bool IsDefaultCtor { get; set; }
|
||||||
}
|
}
|
||||||
public enum ReadAnonymousTypeInfoConsturctorType { Arguments, Properties }
|
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ namespace FreeSql.Internal
|
|||||||
var columnsList = new List<ColumnInfo>();
|
var columnsList = new List<ColumnInfo>();
|
||||||
foreach (var p in trytb.Properties.Values)
|
foreach (var p in trytb.Properties.Values)
|
||||||
{
|
{
|
||||||
var setMethod = p.GetSetMethod(); //trytb.Type.GetMethod($"set_{p.Name}");
|
var setMethod = p.GetSetMethod(true); //trytb.Type.GetMethod($"set_{p.Name}");
|
||||||
var colattr = common.GetEntityColumnAttribute(entity, p);
|
var colattr = common.GetEntityColumnAttribute(entity, p);
|
||||||
var tp = common.CodeFirst.GetDbInfo(colattr?.MapType ?? p.PropertyType);
|
var tp = common.CodeFirst.GetDbInfo(colattr?.MapType ?? p.PropertyType);
|
||||||
if (setMethod == null || (tp == null && p.PropertyType.IsValueType)) // 属性没有 set自动忽略
|
if (setMethod == null || (tp == null && p.PropertyType.IsValueType)) // 属性没有 set自动忽略
|
||||||
@ -1200,7 +1200,7 @@ namespace FreeSql.Internal
|
|||||||
this.Value = value;
|
this.Value = value;
|
||||||
this.DataIndex = dataIndex;
|
this.DataIndex = dataIndex;
|
||||||
}
|
}
|
||||||
public static ConstructorInfo Constructor = typeof(RowInfo).GetConstructor(new[] { typeof(object), typeof(int) });
|
public static ConstructorInfo Constructor = typeof(RowInfo). GetConstructor(new[] { typeof(object), typeof(int) });
|
||||||
public static PropertyInfo PropertyValue = typeof(RowInfo).GetProperty("Value");
|
public static PropertyInfo PropertyValue = typeof(RowInfo).GetProperty("Value");
|
||||||
public static PropertyInfo PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex");
|
public static PropertyInfo PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex");
|
||||||
}
|
}
|
||||||
@ -1342,14 +1342,15 @@ namespace FreeSql.Internal
|
|||||||
var readpkvalExp = Expression.Variable(typeof(object), "isnull3val");
|
var readpkvalExp = Expression.Variable(typeof(object), "isnull3val");
|
||||||
var indexesLengthExp = Expression.Variable(typeof(int), "indexesLength");
|
var indexesLengthExp = Expression.Variable(typeof(int), "indexesLength");
|
||||||
var blockExp = new List<Expression>();
|
var blockExp = new List<Expression>();
|
||||||
var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First();
|
var newExp = type.InternalNewExpression();
|
||||||
var ctorParms = ctor.GetParameters();
|
if (false && newExp.Arguments.Count > 0)
|
||||||
if (ctorParms.Length > 0)
|
|
||||||
{
|
{
|
||||||
|
#region 按构造参数读取数据,此功能暂时关闭
|
||||||
|
/*
|
||||||
blockExp.AddRange(new Expression[] {
|
blockExp.AddRange(new Expression[] {
|
||||||
Expression.Assign(readpknullExp, Expression.Constant(false))
|
Expression.Assign(readpknullExp, Expression.Constant(false))
|
||||||
});
|
});
|
||||||
foreach (var ctorParm in ctorParms)
|
foreach (var ctorParm in newExp.Constructor.GetParameters())
|
||||||
{
|
{
|
||||||
if (typetb.ColumnsByCsIgnore.ContainsKey(ctorParm.Name)) continue;
|
if (typetb.ColumnsByCsIgnore.ContainsKey(ctorParm.Name)) continue;
|
||||||
var readType = typetb.ColumnsByCs.TryGetValue(ctorParm.Name, out var trycol) ? trycol.Attribute.MapType : ctorParm.ParameterType;
|
var readType = typetb.ColumnsByCs.TryGetValue(ctorParm.Name, out var trycol) ? trycol.Attribute.MapType : ctorParm.ParameterType;
|
||||||
@ -1419,33 +1420,35 @@ namespace FreeSql.Internal
|
|||||||
);
|
);
|
||||||
|
|
||||||
blockExp.AddRange(new Expression[] {
|
blockExp.AddRange(new Expression[] {
|
||||||
Expression.Assign(tryidxExp, dataIndexExp),
|
Expression.Assign(tryidxExp, dataIndexExp),
|
||||||
readVal,
|
readVal,
|
||||||
Expression.Assign(readExp, readExpAssign),
|
Expression.Assign(readExp, readExpAssign),
|
||||||
Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
|
Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
|
||||||
Expression.Assign(dataIndexExp, readExpDataIndex)
|
Expression.Assign(dataIndexExp, readExpDataIndex)
|
||||||
),
|
),
|
||||||
Expression.Block(ispkExp)
|
Expression.Block(ispkExp)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
blockExp.Add(
|
blockExp.Add(
|
||||||
Expression.IfThen(
|
Expression.IfThen(
|
||||||
Expression.IsFalse(readpknullExp),
|
Expression.IsFalse(readpknullExp),
|
||||||
Expression.Assign(retExp, Expression.New(ctor, readExpValueParms))
|
Expression.Assign(retExp, Expression.New(newExp.Constructor, readExpValueParms))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
blockExp.AddRange(new Expression[] {
|
blockExp.AddRange(new Expression[] {
|
||||||
Expression.Assign(retExp, Expression.New(ctor)),
|
Expression.Assign(retExp, newExp),
|
||||||
Expression.Assign(indexesLengthExp, Expression.Constant(0)),
|
Expression.Assign(indexesLengthExp, Expression.Constant(0)),
|
||||||
Expression.IfThen(
|
Expression.IfThen(
|
||||||
Expression.NotEqual(indexesExp, Expression.Constant(null)),
|
Expression.NotEqual(indexesExp, Expression.Constant(null)),
|
||||||
Expression.Assign(indexesLengthExp, Expression.ArrayLength(indexesExp))
|
Expression.Assign(indexesLengthExp, Expression.ArrayLength(indexesExp))
|
||||||
),
|
),
|
||||||
Expression.Assign(readpknullExp, Expression.Constant(false))
|
Expression.Assign(readpknullExp, Expression.Constant(false))
|
||||||
});
|
});
|
||||||
|
|
||||||
var props = type.GetPropertiesDictIgnoreCase().Values;
|
var props = type.GetPropertiesDictIgnoreCase().Values;
|
||||||
var propIndex = 0;
|
var propIndex = 0;
|
||||||
@ -1459,7 +1462,7 @@ namespace FreeSql.Internal
|
|||||||
var readType = typetb.ColumnsByCs.TryGetValue(prop.Name, out var trycol) ? trycol.Attribute.MapType : prop.PropertyType;
|
var readType = typetb.ColumnsByCs.TryGetValue(prop.Name, out var trycol) ? trycol.Attribute.MapType : prop.PropertyType;
|
||||||
|
|
||||||
var ispkExp = new List<Expression>();
|
var ispkExp = new List<Expression>();
|
||||||
var propGetSetMethod = prop.GetSetMethod();
|
var propGetSetMethod = prop.GetSetMethod(true);
|
||||||
Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, tryidxExp));
|
Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, tryidxExp));
|
||||||
Expression readExpAssign = null; //加速缓存
|
Expression readExpAssign = null; //加速缓存
|
||||||
if (readType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor,
|
if (readType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor,
|
||||||
@ -1524,30 +1527,30 @@ namespace FreeSql.Internal
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
blockExp.AddRange(new Expression[] {
|
blockExp.AddRange(new Expression[] {
|
||||||
//以下注释部分为【严格读取】,会损失一点性能,使用 select * from xxx 与属性映射赋值
|
//以下注释部分为【严格读取】,会损失一点性能,使用 select * from xxx 与属性映射赋值
|
||||||
Expression.IfThenElse(
|
Expression.IfThenElse(
|
||||||
Expression.LessThan(Expression.Constant(propIndex), indexesLengthExp),
|
Expression.LessThan(Expression.Constant(propIndex), indexesLengthExp),
|
||||||
Expression.Assign(tryidxExp, Expression.ArrayAccess(indexesExp, Expression.Constant(propIndex))),
|
Expression.Assign(tryidxExp, Expression.ArrayAccess(indexesExp, Expression.Constant(propIndex))),
|
||||||
Expression.Assign(tryidxExp, dataIndexExp)
|
Expression.Assign(tryidxExp, dataIndexExp)
|
||||||
),
|
),
|
||||||
Expression.IfThen(
|
Expression.IfThen(
|
||||||
Expression.GreaterThanOrEqual(tryidxExp, Expression.Constant(0)),
|
Expression.GreaterThanOrEqual(tryidxExp, Expression.Constant(0)),
|
||||||
Expression.Block(
|
Expression.Block(
|
||||||
readVal,
|
readVal,
|
||||||
Expression.Assign(readExp, readExpAssign),
|
Expression.Assign(readExp, readExpAssign),
|
||||||
Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
|
Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
|
||||||
Expression.Assign(dataIndexExp, readExpDataIndex)),
|
Expression.Assign(dataIndexExp, readExpDataIndex)),
|
||||||
Expression.Block(ispkExp)
|
Expression.Block(ispkExp)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
++propIndex;
|
++propIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
blockExp.AddRange(new Expression[] {
|
blockExp.AddRange(new Expression[] {
|
||||||
Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, retExp, dataIndexExp)),
|
Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, retExp, dataIndexExp)),
|
||||||
Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
|
Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
|
||||||
});
|
});
|
||||||
return Expression.Lambda<Func<Type, int[], DbDataReader, int, CommonUtils, RowInfo>>(
|
return Expression.Lambda<Func<Type, int[], DbDataReader, int, CommonUtils, RowInfo>>(
|
||||||
Expression.Block(new[] { retExp, readExp, tryidxExp, readpknullExp, readpkvalExp, readExpsIndex, indexesLengthExp }.Concat(readExpValueParms), blockExp), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile();
|
Expression.Block(new[] { retExp, readExp, tryidxExp, readpknullExp, readpkvalExp, readExpsIndex, indexesLengthExp }.Concat(readExpValueParms), blockExp), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile();
|
||||||
});
|
});
|
||||||
@ -1616,7 +1619,7 @@ namespace FreeSql.Internal
|
|||||||
static MethodInfo MethodBigIntegerParse = typeof(Utils).GetMethod("ToBigInteger", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(string) }, null);
|
static MethodInfo MethodBigIntegerParse = typeof(Utils).GetMethod("ToBigInteger", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(string) }, null);
|
||||||
static PropertyInfo PropertyDateTimeOffsetDateTime = typeof(DateTimeOffset).GetProperty("DateTime", BindingFlags.Instance | BindingFlags.Public);
|
static PropertyInfo PropertyDateTimeOffsetDateTime = typeof(DateTimeOffset).GetProperty("DateTime", BindingFlags.Instance | BindingFlags.Public);
|
||||||
static PropertyInfo PropertyDateTimeTicks = typeof(DateTime).GetProperty("Ticks", BindingFlags.Instance | BindingFlags.Public);
|
static PropertyInfo PropertyDateTimeTicks = typeof(DateTime).GetProperty("Ticks", BindingFlags.Instance | BindingFlags.Public);
|
||||||
static ConstructorInfo CtorDateTimeOffsetArgsTicks = typeof(DateTimeOffset).GetConstructor(new[] { typeof(long), typeof(TimeSpan) });
|
static ConstructorInfo CtorDateTimeOffsetArgsTicks = typeof(DateTimeOffset). GetConstructor(new[] { typeof(long), typeof(TimeSpan) });
|
||||||
|
|
||||||
public static ConcurrentBag<Func<LabelTarget, Expression, Type, Expression>> GetDataReaderValueBlockExpressionSwitchTypeFullName = new ConcurrentBag<Func<LabelTarget, Expression, Type, Expression>>();
|
public static ConcurrentBag<Func<LabelTarget, Expression, Type, Expression>> GetDataReaderValueBlockExpressionSwitchTypeFullName = new ConcurrentBag<Func<LabelTarget, Expression, Type, Expression>>();
|
||||||
public static ConcurrentBag<Func<LabelTarget, Expression, Expression, Type, Expression>> GetDataReaderValueBlockExpressionObjectToStringIfThenElse = new ConcurrentBag<Func<LabelTarget, Expression, Expression, Type, Expression>>();
|
public static ConcurrentBag<Func<LabelTarget, Expression, Expression, Type, Expression>> GetDataReaderValueBlockExpressionObjectToStringIfThenElse = new ConcurrentBag<Func<LabelTarget, Expression, Expression, Type, Expression>>();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user