From d5ed1c8a30c5ba6f6304ab1028fb6c93f25d3285 Mon Sep 17 00:00:00 2001
From: 28810 <28810@YEXIANGQIN>
Date: Sun, 22 Dec 2019 20:10:21 +0800
Subject: [PATCH] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E5=AE=9E=E4=BD=93?=
=?UTF-8?q?=E5=9F=BA=E7=B1=BB=E7=9A=84=E5=B1=9E=E6=80=A7=E4=BD=8D=E7=BD=AE?=
=?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=85=88=E6=8E=92=E5=9C=A8=E6=9C=80=E5=89=8D?=
=?UTF-8?q?=E9=9D=A2=EF=BC=9B=20#164=20-=20=E6=95=B4=E7=90=86=20=E5=AE=9E?=
=?UTF-8?q?=E4=BD=93=E7=B1=BB=20Ctor=20=E6=9C=89=E6=9E=84=E9=80=A0?=
=?UTF-8?q?=E5=87=BD=E6=95=B0=E7=9A=84=E6=98=A0=E5=B0=84=E5=A4=84=E7=90=86?=
=?UTF-8?q?=EF=BC=9B#164=20[wiki](https://github.com/2881099/FreeSql/wiki/?=
=?UTF-8?q?%e8%bf%94%e5%9b%9e%e6%95%b0%e6%8d%ae#dto-%E6%98%A0%E5%B0%84%E6%?=
=?UTF-8?q?9F%A5%E8%AF%A2)=20-=20=E4=BC=98=E5=8C=96=20=E5=AE=9E=E4=BD=93?=
=?UTF-8?q?=E5=B1=9E=E6=80=A7=EF=BC=8C=E6=94=AF=E6=8C=81=20protected=20set?=
=?UTF-8?q?=20=E5=B1=9E=E6=80=A7=EF=BC=9B#164?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Extensions/DependencyInjection.cs | 2 +-
FreeSql.DbContext/FreeSql.DbContext.xml | 7 -
.../MySql/Curd/MySqlSelectTest.cs | 17 ++
.../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 17 +-
FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 20 +-
FreeSql/Internal/CommonExpression.cs | 175 ++++++++++--------
.../SelectProvider/Select0Provider.cs | 20 +-
.../SelectProvider/Select10Provider.cs | 4 +-
.../SelectProvider/Select1Provider.cs | 9 +-
.../SelectProvider/Select2Provider.cs | 4 +-
.../SelectProvider/Select3Provider.cs | 4 +-
.../SelectProvider/Select4Provider.cs | 4 +-
.../SelectProvider/Select5Provider.cs | 4 +-
.../SelectProvider/Select6Provider.cs | 4 +-
.../SelectProvider/Select7Provider.cs | 4 +-
.../SelectProvider/Select8Provider.cs | 4 +-
.../SelectProvider/Select9Provider.cs | 4 +-
.../Internal/Model/ReadAnonymousTypeInfo.cs | 3 +-
FreeSql/Internal/UtilsExpressionTree.cs | 95 +++++-----
19 files changed, 226 insertions(+), 175 deletions(-)
diff --git a/FreeSql.DbContext/Extensions/DependencyInjection.cs b/FreeSql.DbContext/Extensions/DependencyInjection.cs
index ebd575e1..cad5047f 100644
--- a/FreeSql.DbContext/Extensions/DependencyInjection.cs
+++ b/FreeSql.DbContext/Extensions/DependencyInjection.cs
@@ -15,7 +15,7 @@ namespace FreeSql
DbContext ctx = null;
try
{
- var ctor = dbContextType.GetConstructors().FirstOrDefault();
+ var ctor = dbContextType. GetConstructors().FirstOrDefault();
var ctorParams = ctor.GetParameters().Select(a => sp.GetService(a.ParameterType)).ToArray();
ctx = Activator.CreateInstance(dbContextType, ctorParams) as DbContext;
}
diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml
index d9f91124..dc0203b8 100644
--- a/FreeSql.DbContext/FreeSql.DbContext.xml
+++ b/FreeSql.DbContext/FreeSql.DbContext.xml
@@ -110,13 +110,6 @@
清空状态数据
-
-
- 根据 lambda 条件删除数据
-
-
-
-
添加
diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs
index c76fea46..0cf69bea 100644
--- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs
@@ -1056,6 +1056,23 @@ WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title`
a.Id,
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
diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs
index 6ad6d8e6..6a0da303 100644
--- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs
@@ -17,11 +17,7 @@ namespace FreeSql.Tests.MySql
var sql = g.mysql.CodeFirst.GetComparisonDDLStatements<ı2>();
g.mysql.CodeFirst.SyncStructure<ı2>();
- var item = new ı2
- {
- = "Ա",
- ʱ = DateTime.Now
- };
+ var item = ı2.Create("Ա", DateTime.Now);
Assert.Equal(1, g.mysql.Insert<ı2>().AppendData(item).ExecuteAffrows());
Assert.NotEqual(Guid.Empty, item.);
var item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First();
@@ -32,12 +28,17 @@ namespace FreeSql.Tests.MySql
class ı2
{
[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)]
- public DateTime ʱ { get; set; }
+ public DateTime ʱ { get; protected set; }
+
+ public static ı2 Create(string title, DateTime ctm)
+ {
+ return new ı2 { = title, ʱ = ctm };
+ }
}
[Fact]
diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs
index 86449244..f04dc599 100644
--- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs
+++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs
@@ -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 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));
- static ConcurrentDictionary _dicGetDefaultValueFirstConstructorsParameters = new ConcurrentDictionary();
public static object CreateInstanceGetDefaultValue(this Type that)
{
if (that == null) return null;
if (that == typeof(string)) return default(string);
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);
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 _dicInternalGetTypeConstructor0OrFirst = new ConcurrentDictionary();
+ 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> _dicGetPropertiesDictIgnoreCase = new ConcurrentDictionary>();
public static Dictionary 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(StringComparer.CurrentCultureIgnoreCase);
foreach (var prop in props)
{
diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs
index ab2373ff..ec8770fc 100644
--- a/FreeSql/Internal/CommonExpression.cs
+++ b/FreeSql/Internal/CommonExpression.cs
@@ -52,7 +52,8 @@ namespace FreeSql.Internal
var constExpValue = constExp.Value?.ToString() ?? "NULL";
if (constExpValue == string.Empty) constExpValue = _common.FormatSql("{0}", "");
parent.DbField = constExpValue;
- } else
+ }
+ else
parent.DbField = _common.FormatSql("{0}", constExp?.Value);
field.Append(", ").Append(parent.DbField);
if (index >= 0) field.Append(" as").Append(++index);
@@ -82,8 +83,8 @@ namespace FreeSql.Internal
var map = new List();
ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, getSelectGroupingMapString);
var tb = parent.Table = map.First().Table.Table;
- parent.Consturctor = tb.Type.GetConstructor(new Type[0]);
- parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
+ parent.CsType = tb.Type;
+ parent.Consturctor = tb.Type.InternalGetTypeConstructor0OrFirst();
parent.IsEntity = true;
for (var idx = 0; idx < map.Count; idx++)
{
@@ -113,10 +114,25 @@ namespace FreeSql.Internal
return false;
case ExpressionType.MemberInit:
var initExp = exp as MemberInitExpression;
- parent.Consturctor = initExp.NewExpression.Type.GetConstructors()[0];
- parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
-
- if (isAllDtoMap && _tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type)
+ parent.CsType = initExp.Type;
+ parent.Consturctor = initExp.NewExpression.Constructor;
+ if (initExp.NewExpression?.Arguments.Count > 0)
+ {
+ //处理构造参数
+ 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 映射
var dtoProps = initExp.NewExpression.Type.GetPropertiesDictIgnoreCase().Values;
@@ -124,26 +140,26 @@ namespace FreeSql.Internal
{
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,
- CsType = trydtocol.CsType, // dtoProp.PropertyType,
- MapType = trydtocol.Attribute.MapType
- };
- parent.Childs.Add(child);
- if (dtTb.Parameter != null)
- 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);
- if (index >= 0) field.Append(" as").Append(++index);
- }
- break;
+ Property = dtoProp,
+ CsName = dtoProp.Name,
+ CsType = trydtocol.CsType, // dtoProp.PropertyType,
+ MapType = trydtocol.Attribute.MapType
+ };
+ parent.Childs.Add(child);
+ if (dtTb.Parameter != null)
+ 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);
+ if (index >= 0) field.Append(" as").Append(++index);
}
+ break;
}
}
}
@@ -169,15 +185,27 @@ namespace FreeSql.Internal
return true;
case ExpressionType.New:
var newExp = exp as NewExpression;
- parent.Consturctor = newExp.Type.GetConstructors()[0];
- parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Arguments;
- if (newExp.Members?.Count > 0)
+ parent.CsType = newExp.Type;
+ parent.Consturctor = newExp.Constructor;
+ 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
{
- Property = newExp.Type.GetProperty(newExp.Members[a].Name, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance),
+ Property = null,
CsName = newExp.Members[a].Name,
CsType = newExp.Arguments[a].Type,
MapType = newExp.Arguments[a].Type
@@ -188,37 +216,37 @@ namespace FreeSql.Internal
}
else
{
+ parent.IsDefaultCtor = true;
//dto 映射
- parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
var dtoProps2 = newExp.Type.GetPropertiesDictIgnoreCase().Values;
foreach (var dtoProp in dtoProps2)
{
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,
- CsType = trydtocol.CsType, //dtoProp.PropertyType,
- MapType = trydtocol.Attribute.MapType
- };
- parent.Childs.Add(child);
- if (dtTb.Parameter != null)
- 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);
- if (index >= 0) field.Append(" as").Append(++index);
- }
- break;
+ Property = dtoProp,
+ CsName = dtoProp.Name,
+ CsType = trydtocol.CsType, //dtoProp.PropertyType,
+ MapType = trydtocol.Attribute.MapType
+ };
+ parent.Childs.Add(child);
+ if (dtTb.Parameter != null)
+ 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);
+ if (index >= 0) field.Append(" as").Append(++index);
}
+ 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;
}
parent.DbField = $"({ExpressionLambdaToSql(exp, getTSC())})";
@@ -247,33 +275,30 @@ namespace FreeSql.Internal
objval = Utils.GetDataReaderValue(parent.Property.PropertyType, 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 args = new object[parent.Childs.Count];
- for (var a = 0; a < parent.Childs.Count; a++)
- {
- 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;
+ var ctorParms = new object[ctorParmsLength];
+ for (var c = 0; c < ctorParmsLength; c++)
+ ctorParms[c] = ReadAnonymous(parent.Childs[c], dr, ref index, notRead, null);
+ ret = parent.Consturctor.Invoke(ctorParms);
}
- 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
{
diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs
index 0a36fad7..2881b8fb 100644
--- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs
+++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs
@@ -546,7 +546,6 @@ namespace FreeSql.Internal.CommonProvider
_commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null, _whereCascadeExpression, true);
return (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null);
}
- static ConcurrentDictionary _dicConstructor = new ConcurrentDictionary();
static ConcurrentDictionary _dicGetAllFieldExpressionTree = new ConcurrentDictionary();
public class GetAllFieldExpressionTreeInfo
{
@@ -568,9 +567,8 @@ namespace FreeSql.Internal.CommonProvider
var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue);
var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex);
var blockExp = new List();
- 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(retExp, type.InternalNewExpression()),
Expression.Assign(dataIndexExp, Expression.Constant(0))
});
//typeof(Topic).GetMethod("get_Type").IsVirtual
@@ -711,9 +709,8 @@ namespace FreeSql.Internal.CommonProvider
var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue);
var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex);
var blockExp = new List();
- 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(retExp, type.InternalNewExpression()),
Expression.Assign(dataIndexExp, Expression.Constant(0))
});
//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; //加速缓存
if (prop.PropertyType.IsArray) readExpAssign = Expression.New(Utils.RowInfo.Constructor,
Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp)),
@@ -836,9 +833,9 @@ namespace FreeSql.Internal.CommonProvider
protected (ReadAnonymousTypeInfo map, string field) GetAllFieldReflection()
{
var tb1 = _tables.First().Table;
- var type = tb1.Type;
- var constructor = _dicConstructor.GetOrAdd(type, s => type.GetConstructor(new Type[0]));
- var map = new ReadAnonymousTypeInfo { Consturctor = constructor, ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties };
+ var type = tb1.TypeLazy ?? tb1.Type;
+ var constructor = type.InternalGetTypeConstructor0OrFirst();
+ var map = new ReadAnonymousTypeInfo { CsType = type, Consturctor = constructor, IsEntity = true };
var field = new StringBuilder();
var dicfield = new Dictionary();
@@ -862,8 +859,9 @@ namespace FreeSql.Internal.CommonProvider
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) continue;
- child.Consturctor = tb2.Table.Type.GetConstructor(new Type[0]);
- child.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
+ child.CsType = (tb2.Table.TypeLazy ?? tb2.Table.Type);
+ child.Consturctor = child.CsType.InternalGetTypeConstructor0OrFirst();
+ child.IsEntity = true;
foreach (var col2 in tb2.Table.Columns.Values)
{
if (index > 0) field.Append(", ");
diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs
index fd73c7c0..4ab36722 100644
--- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs
+++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs
@@ -101,8 +101,8 @@ namespace FreeSql.Internal.CommonProvider
List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector());
Expression> GetToListDtoSelector()
{
- var ctor = typeof(TDto).GetConstructor(new Type[0]);
- return Expression.Lambda>(Expression.New(ctor),
+ return Expression.Lambda>(
+ typeof(TDto).InternalNewExpression(),
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
Expression.Parameter(typeof(T2), "b"),
Expression.Parameter(typeof(T3), "c"),
diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs
index 46667c86..ea6e9ff6 100644
--- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs
+++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs
@@ -172,8 +172,8 @@ namespace FreeSql.Internal.CommonProvider
public List ToList() => ToList(GetToListDtoSelector());
Expression> GetToListDtoSelector()
{
- var ctor = typeof(TDto).GetConstructor(new Type[0]);
- return Expression.Lambda>(Expression.New(ctor),
+ return Expression.Lambda>(
+ typeof(TDto).InternalNewExpression(),
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"));
}
@@ -884,8 +884,9 @@ namespace FreeSql.Internal.CommonProvider
{
var field = new StringBuilder();
var read = new ReadAnonymousTypeInfo();
- read.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
- read.Consturctor = (tbrefMid.TypeLazy ?? tbrefMid.Type).GetConstructor(new Type[0]);
+ read.CsType = (tbrefMid.TypeLazy ?? tbrefMid.Type);
+ read.Consturctor = read.CsType.InternalGetTypeConstructor0OrFirst();
+ read.IsEntity = true;
read.Table = tbrefMid;
foreach (var col in tbrefMid.Columns.Values)
{
diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs
index beaa1d50..d8ed2fe8 100644
--- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs
+++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs
@@ -86,8 +86,8 @@ namespace FreeSql.Internal.CommonProvider
List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector());
Expression> GetToListDtoSelector()
{
- var ctor = typeof(TDto).GetConstructor(new Type[0]);
- return Expression.Lambda>(Expression.New(ctor),
+ return Expression.Lambda>(
+ typeof(TDto).InternalNewExpression(),
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
Expression.Parameter(typeof(T2), "b"));
}
diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs
index 5f49d8cf..03cf62e3 100644
--- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs
+++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs
@@ -88,8 +88,8 @@ namespace FreeSql.Internal.CommonProvider
List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector());
Expression> GetToListDtoSelector()
{
- var ctor = typeof(TDto).GetConstructor(new Type[0]);
- return Expression.Lambda>(Expression.New(ctor),
+ return Expression.Lambda>(
+ typeof(TDto).InternalNewExpression(),
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
Expression.Parameter(typeof(T2), "b"),
Expression.Parameter(typeof(T3), "c"));
diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs
index 075397f7..e006c78b 100644
--- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs
+++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs
@@ -90,8 +90,8 @@ namespace FreeSql.Internal.CommonProvider
List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector());
Expression> GetToListDtoSelector()
{
- var ctor = typeof(TDto).GetConstructor(new Type[0]);
- return Expression.Lambda>(Expression.New(ctor),
+ return Expression.Lambda>(
+ typeof(TDto).InternalNewExpression(),
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
Expression.Parameter(typeof(T2), "b"),
Expression.Parameter(typeof(T3), "c"),
diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs
index d21e16a2..76e9ddbc 100644
--- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs
+++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs
@@ -92,8 +92,8 @@ namespace FreeSql.Internal.CommonProvider
List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector());
Expression> GetToListDtoSelector()
{
- var ctor = typeof(TDto).GetConstructor(new Type[0]);
- return Expression.Lambda>(Expression.New(ctor),
+ return Expression.Lambda>(
+ typeof(TDto).InternalNewExpression(),
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
Expression.Parameter(typeof(T2), "b"),
Expression.Parameter(typeof(T3), "c"),
diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs
index 5669598d..81fe63cf 100644
--- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs
+++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs
@@ -94,8 +94,8 @@ namespace FreeSql.Internal.CommonProvider
List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector());
Expression> GetToListDtoSelector()
{
- var ctor = typeof(TDto).GetConstructor(new Type[0]);
- return Expression.Lambda>(Expression.New(ctor),
+ return Expression.Lambda>(
+ typeof(TDto).InternalNewExpression(),
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
Expression.Parameter(typeof(T2), "b"),
Expression.Parameter(typeof(T3), "c"),
diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs
index a8f94ac3..f3a953e6 100644
--- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs
+++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs
@@ -96,8 +96,8 @@ namespace FreeSql.Internal.CommonProvider
List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector());
Expression> GetToListDtoSelector()
{
- var ctor = typeof(TDto).GetConstructor(new Type[0]);
- return Expression.Lambda>(Expression.New(ctor),
+ return Expression.Lambda>(
+ typeof(TDto).InternalNewExpression(),
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
Expression.Parameter(typeof(T2), "b"),
Expression.Parameter(typeof(T3), "c"),
diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs
index f85d2df9..79e5f4af 100644
--- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs
+++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs
@@ -99,8 +99,8 @@ namespace FreeSql.Internal.CommonProvider
Expression> GetToListDtoSelector()
{
- var ctor = typeof(TDto).GetConstructor(new Type[0]);
- return Expression.Lambda>(Expression.New(ctor),
+ return Expression.Lambda>(
+ typeof(TDto).InternalNewExpression(),
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
Expression.Parameter(typeof(T2), "b"),
Expression.Parameter(typeof(T3), "c"),
diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs
index d03d4ba0..ebc99041 100644
--- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs
+++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs
@@ -99,8 +99,8 @@ namespace FreeSql.Internal.CommonProvider
List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector());
Expression> GetToListDtoSelector()
{
- var ctor = typeof(TDto).GetConstructor(new Type[0]);
- return Expression.Lambda>(Expression.New(ctor),
+ return Expression.Lambda>(
+ typeof(TDto).InternalNewExpression(),
_tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
Expression.Parameter(typeof(T2), "b"),
Expression.Parameter(typeof(T3), "c"),
diff --git a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs
index 3ca01e00..d252db75 100644
--- a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs
+++ b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs
@@ -13,10 +13,9 @@ namespace FreeSql.Internal.Model
public Type MapType { get; set; }
public string DbField { get; set; }
public ConstructorInfo Consturctor { get; set; }
- public ReadAnonymousTypeInfoConsturctorType ConsturctorType { get; set; }
public List Childs = new List();
public TableInfo Table { get; set; }
public bool IsEntity { get; set; }
+ public bool IsDefaultCtor { get; set; }
}
- public enum ReadAnonymousTypeInfoConsturctorType { Arguments, Properties }
}
diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs
index c8b1b92f..83002513 100644
--- a/FreeSql/Internal/UtilsExpressionTree.cs
+++ b/FreeSql/Internal/UtilsExpressionTree.cs
@@ -72,7 +72,7 @@ namespace FreeSql.Internal
var columnsList = new List();
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 tp = common.CodeFirst.GetDbInfo(colattr?.MapType ?? p.PropertyType);
if (setMethod == null || (tp == null && p.PropertyType.IsValueType)) // 属性没有 set自动忽略
@@ -1200,7 +1200,7 @@ namespace FreeSql.Internal
this.Value = value;
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 PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex");
}
@@ -1342,14 +1342,15 @@ namespace FreeSql.Internal
var readpkvalExp = Expression.Variable(typeof(object), "isnull3val");
var indexesLengthExp = Expression.Variable(typeof(int), "indexesLength");
var blockExp = new List();
- var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First();
- var ctorParms = ctor.GetParameters();
- if (ctorParms.Length > 0)
+ var newExp = type.InternalNewExpression();
+ if (false && newExp.Arguments.Count > 0)
{
+ #region 按构造参数读取数据,此功能暂时关闭
+ /*
blockExp.AddRange(new Expression[] {
- Expression.Assign(readpknullExp, Expression.Constant(false))
- });
- foreach (var ctorParm in ctorParms)
+ Expression.Assign(readpknullExp, Expression.Constant(false))
+ });
+ foreach (var ctorParm in newExp.Constructor.GetParameters())
{
if (typetb.ColumnsByCsIgnore.ContainsKey(ctorParm.Name)) continue;
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[] {
- Expression.Assign(tryidxExp, dataIndexExp),
- readVal,
- Expression.Assign(readExp, readExpAssign),
- Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
- Expression.Assign(dataIndexExp, readExpDataIndex)
- ),
- Expression.Block(ispkExp)
- });
+ Expression.Assign(tryidxExp, dataIndexExp),
+ readVal,
+ Expression.Assign(readExp, readExpAssign),
+ Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
+ Expression.Assign(dataIndexExp, readExpDataIndex)
+ ),
+ Expression.Block(ispkExp)
+ });
}
blockExp.Add(
Expression.IfThen(
Expression.IsFalse(readpknullExp),
- Expression.Assign(retExp, Expression.New(ctor, readExpValueParms))
+ Expression.Assign(retExp, Expression.New(newExp.Constructor, readExpValueParms))
)
);
+ */
+ #endregion
}
else
{
blockExp.AddRange(new Expression[] {
- Expression.Assign(retExp, Expression.New(ctor)),
- Expression.Assign(indexesLengthExp, Expression.Constant(0)),
- Expression.IfThen(
- Expression.NotEqual(indexesExp, Expression.Constant(null)),
- Expression.Assign(indexesLengthExp, Expression.ArrayLength(indexesExp))
- ),
- Expression.Assign(readpknullExp, Expression.Constant(false))
- });
+ Expression.Assign(retExp, newExp),
+ Expression.Assign(indexesLengthExp, Expression.Constant(0)),
+ Expression.IfThen(
+ Expression.NotEqual(indexesExp, Expression.Constant(null)),
+ Expression.Assign(indexesLengthExp, Expression.ArrayLength(indexesExp))
+ ),
+ Expression.Assign(readpknullExp, Expression.Constant(false))
+ });
var props = type.GetPropertiesDictIgnoreCase().Values;
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 ispkExp = new List();
- var propGetSetMethod = prop.GetSetMethod();
+ var propGetSetMethod = prop.GetSetMethod(true);
Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, tryidxExp));
Expression readExpAssign = null; //加速缓存
if (readType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor,
@@ -1524,30 +1527,30 @@ namespace FreeSql.Internal
)
);
blockExp.AddRange(new Expression[] {
- //以下注释部分为【严格读取】,会损失一点性能,使用 select * from xxx 与属性映射赋值
- Expression.IfThenElse(
- Expression.LessThan(Expression.Constant(propIndex), indexesLengthExp),
- Expression.Assign(tryidxExp, Expression.ArrayAccess(indexesExp, Expression.Constant(propIndex))),
- Expression.Assign(tryidxExp, dataIndexExp)
- ),
- Expression.IfThen(
- Expression.GreaterThanOrEqual(tryidxExp, Expression.Constant(0)),
- Expression.Block(
- readVal,
- Expression.Assign(readExp, readExpAssign),
- Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
- Expression.Assign(dataIndexExp, readExpDataIndex)),
- Expression.Block(ispkExp)
+ //以下注释部分为【严格读取】,会损失一点性能,使用 select * from xxx 与属性映射赋值
+ Expression.IfThenElse(
+ Expression.LessThan(Expression.Constant(propIndex), indexesLengthExp),
+ Expression.Assign(tryidxExp, Expression.ArrayAccess(indexesExp, Expression.Constant(propIndex))),
+ Expression.Assign(tryidxExp, dataIndexExp)
+ ),
+ Expression.IfThen(
+ Expression.GreaterThanOrEqual(tryidxExp, Expression.Constant(0)),
+ Expression.Block(
+ readVal,
+ Expression.Assign(readExp, readExpAssign),
+ Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
+ Expression.Assign(dataIndexExp, readExpDataIndex)),
+ Expression.Block(ispkExp)
+ )
)
- )
- });
+ });
++propIndex;
}
}
blockExp.AddRange(new Expression[] {
- Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, retExp, dataIndexExp)),
- Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
- });
+ Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, retExp, dataIndexExp)),
+ Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
+ });
return Expression.Lambda>(
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 PropertyInfo PropertyDateTimeOffsetDateTime = typeof(DateTimeOffset).GetProperty("DateTime", 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> GetDataReaderValueBlockExpressionSwitchTypeFullName = new ConcurrentBag>();
public static ConcurrentBag> GetDataReaderValueBlockExpressionObjectToStringIfThenElse = new ConcurrentBag>();