From 5782d6e5173b80324820b604eca7909d8932c7fa Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Wed, 18 Oct 2023 20:25:03 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Aop.AuditDataReader=20?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=B1=9E=E6=80=A7=20PropertyInfo=EF=BC=8C?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E8=87=AA=E5=AE=9A=E4=B9=89=E6=8B=A6=E6=88=AA?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 103 ++++++++++++++++++ FreeSql/Interface/IAop.cs | 7 +- FreeSql/Internal/CommonExpression.cs | 2 +- .../SelectProvider/Select0ProviderReader.cs | 15 ++- FreeSql/Internal/UtilsExpressionTree.cs | 32 +++--- 5 files changed, 131 insertions(+), 28 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 52f69aab..0700ca6b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1084,6 +1084,82 @@ + + + 动态创建实体类型 + + + + + 配置Class + + 类名 + 类标记的特性[Table(Name = "xxx")] [Index(xxxx)] + + + + + 配置属性 + + 属性名称 + 属性类型 + 属性标记的特性-支持多个 + + + + + 配置属性 + + 属性名称 + 属性类型 + 该属性是否重写父类属性 + 属性标记的特性-支持多个 + + + + + 配置属性 + + 属性名称 + 属性类型 + 该属性是否重写父类属性 + 属性默认值 + 属性标记的特性-支持多个 + + + + + 配置父类 + + 父类类型 + + + + + Override属性 + + + + + + Emit动态创建出Class - Type + + + + + + 首字母小写 + + + + + + + 首字母大写 + + + + 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null @@ -3992,6 +4068,11 @@ DataReader 对应的 Index 位置 + + + DataReader 对应的 PropertyInfo + + 获取 Index 对应的值,也可以设置拦截的新值 @@ -5761,6 +5842,28 @@ 请使用 fsql.InsertDict(dict) 方法插入字典数据 + + + 动态构建Class Type + + + + + + 根据字典,创建 table 对应的实体对象 + + + + + + + + 根据实体对象,创建 table 对应的字典 + + + + + C#: that >= between && that <= and diff --git a/FreeSql/Interface/IAop.cs b/FreeSql/Interface/IAop.cs index e4c66df7..6efba9ff 100644 --- a/FreeSql/Interface/IAop.cs +++ b/FreeSql/Interface/IAop.cs @@ -360,10 +360,11 @@ namespace FreeSql.Aop #region AuditDataReader public class AuditDataReaderEventArgs : EventArgs { - public AuditDataReaderEventArgs(DbDataReader dataReader, int index) + public AuditDataReaderEventArgs(DbDataReader dataReader, int index, PropertyInfo property) { this.DataReader = dataReader; this.Index = index; + this.Property = property; } /// @@ -375,6 +376,10 @@ namespace FreeSql.Aop /// public int Index { get; } /// + /// DataReader 对应的 PropertyInfo + /// + public PropertyInfo Property { get; } + /// /// 获取 Index 对应的值,也可以设置拦截的新值 /// public object Value diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 7be3a010..16b5dacc 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -570,7 +570,7 @@ namespace FreeSql.Internal return Utils.GetDataReaderValue(parent.Property.PropertyType, null); return Utils.GetDataReaderValue(parent.CsType, null); } - object objval = Utils.InternalDataReaderGetValue(_common, dr, ++index); // dr.GetValue(++index); + object objval = Utils.InternalDataReaderGetValue(_common, dr, ++index, parent.Property); // dr.GetValue(++index); if (dbValue != null) dbValue.DbValue = objval == DBNull.Value ? null : objval; if (parent.CsType != parent.MapType) objval = Utils.GetDataReaderValue(parent.MapType, objval); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs index 3908e4c0..be40ee34 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -600,7 +600,7 @@ namespace FreeSql.Internal.CommonProvider var name = dr.GetName(a); //expando[name] = row2.GetValue(a); if (expandodic.ContainsKey(name)) continue; - expandodic.Add(name, Utils.InternalDataReaderGetValue(_commonUtils, dr, a)); + expandodic.Add(name, Utils.InternalDataReaderGetValue(_commonUtils, dr, a, null)); } //expando = expandodic; return (T1)((object)expandodic); @@ -682,8 +682,7 @@ namespace FreeSql.Internal.CommonProvider var propGetSetMethod = prop.GetSetMethod(true); Expression readExpAssign = null; //加速缓存 if (prop.PropertyType.IsArray) readExpAssign = Expression.New(Utils.RowInfo.Constructor, - Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(Utils.MethodDataReaderGetValue, new Expression[] { Expression.Constant(_commonUtils), rowExp, dataIndexExp })), - //Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }), + Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(Utils.MethodDataReaderGetValue, new Expression[] { Expression.Constant(_commonUtils), rowExp, dataIndexExp, Expression.Constant(prop) })), Expression.Add(dataIndexExp, Expression.Constant(1)) ); else @@ -692,8 +691,7 @@ namespace FreeSql.Internal.CommonProvider if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GetGenericArguments().First(); if (proptypeGeneric.IsEnum || Utils.dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(Utils.RowInfo.Constructor, - Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(Utils.MethodDataReaderGetValue, new Expression[] { Expression.Constant(_commonUtils), rowExp, dataIndexExp })), - //Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }), + Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(Utils.MethodDataReaderGetValue, new Expression[] { Expression.Constant(_commonUtils), rowExp, dataIndexExp, Expression.Constant(prop) })), Expression.Add(dataIndexExp, Expression.Constant(1)) ); else @@ -739,7 +737,8 @@ namespace FreeSql.Internal.CommonProvider foreach (var col in tb.Table.Columns.Values) { var drvalType = col.Attribute.MapType.NullableTypeOrThis(); - var propGetSetMethod = tb.Table.Properties[col.CsName].GetSetMethod(true); + var colprop = tb.Table.Properties[col.CsName]; + var propGetSetMethod = colprop.GetSetMethod(true); if (col.CsType == col.Attribute.MapType && _orm.Aop.AuditDataReaderHandler == null && _dicMethodDataReaderGetValue.TryGetValue(col.Attribute.MapType.NullableTypeOrThis(), out var drGetValueMethod)) @@ -755,7 +754,7 @@ namespace FreeSql.Internal.CommonProvider { var drvalExpCatch = Utils.GetDataReaderValueBlockExpression( col.CsType, - Expression.Call(Utils.MethodDataReaderGetValue, new Expression[] { Expression.Constant(_commonUtils), rowExp, Expression.Constant(colidx) }) + Expression.Call(Utils.MethodDataReaderGetValue, new Expression[] { Expression.Constant(_commonUtils), rowExp, Expression.Constant(colidx), Expression.Constant(colprop) }) ); blockExp.Add(Expression.TryCatch( Expression.Call(retExp, propGetSetMethod, drvalExp), @@ -780,7 +779,7 @@ namespace FreeSql.Internal.CommonProvider { var drvalExp = Utils.GetDataReaderValueBlockExpression( col.CsType, - Expression.Call(Utils.MethodDataReaderGetValue, new Expression[] { Expression.Constant(_commonUtils), rowExp, Expression.Constant(colidx) }) + Expression.Call(Utils.MethodDataReaderGetValue, new Expression[] { Expression.Constant(_commonUtils), rowExp, Expression.Constant(colidx), Expression.Constant(colprop) }) ); blockExp.Add(Expression.Call(retExp, propGetSetMethod, Expression.Convert(drvalExp, col.CsType))); } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index fc6b3a20..95180312 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1683,12 +1683,12 @@ namespace FreeSql.Internal } internal static MethodInfo MethodDataReaderGetValue = typeof(Utils).GetMethod("InternalDataReaderGetValue", BindingFlags.Static | BindingFlags.NonPublic); internal static PropertyInfo PropertyDataReaderFieldCount = typeof(DbDataReader).GetProperty("FieldCount"); - internal static object InternalDataReaderGetValue(CommonUtils commonUtil, DbDataReader dr, int index) + internal static object InternalDataReaderGetValue(CommonUtils commonUtil, DbDataReader dr, int index, PropertyInfo property) { var orm = commonUtil._orm; if (orm.Aop.AuditDataReaderHandler != null) { - var args = new Aop.AuditDataReaderEventArgs(dr, index); + var args = new Aop.AuditDataReaderEventArgs(dr, index, property); orm.Aop.AuditDataReaderHandler(orm, args); return args.Value; } @@ -1725,8 +1725,7 @@ namespace FreeSql.Internal if (type.IsArray) return Expression.Lambda>( Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(type, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp })), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp }) }), + GetDataReaderValueBlockExpression(type, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp, Expression.Default(typeof(PropertyInfo)) })), Expression.Add(dataIndexExp, Expression.Constant(1)) ), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); @@ -1736,8 +1735,7 @@ namespace FreeSql.Internal dicExecuteArrayRowReadClassOrTuple.ContainsKey(typeGeneric)) return Expression.Lambda>( Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(type, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp })), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp }) }), + GetDataReaderValueBlockExpression(type, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp, Expression.Default(typeof(PropertyInfo)) })), Expression.Add(dataIndexExp, Expression.Constant(1)) ), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); @@ -1757,8 +1755,7 @@ namespace FreeSql.Internal { Expression read2ExpAssign = null; //加速缓存 if (field.FieldType.IsArray) read2ExpAssign = Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(field.FieldType, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp })), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(field.FieldType), Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp }) }), + GetDataReaderValueBlockExpression(field.FieldType, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp, Expression.Default(typeof(PropertyInfo)) })), Expression.Add(dataIndexExp, Expression.Constant(1)) ); else @@ -1767,8 +1764,7 @@ namespace FreeSql.Internal if (fieldtypeGeneric.IsNullableType()) fieldtypeGeneric = fieldtypeGeneric.GetGenericArguments().First(); if (fieldtypeGeneric.IsEnum || dicExecuteArrayRowReadClassOrTuple.ContainsKey(fieldtypeGeneric)) read2ExpAssign = Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(field.FieldType, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp })), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(field.FieldType), Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp }) }), + GetDataReaderValueBlockExpression(field.FieldType, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp, Expression.Default(typeof(PropertyInfo)) })), Expression.Add(dataIndexExp, Expression.Constant(1)) ); else @@ -1809,8 +1805,7 @@ namespace FreeSql.Internal Expression.IfThen( Expression.LessThan(dataIndexExp, rowLenExp), Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(type, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp })), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp }) }), + GetDataReaderValueBlockExpression(type, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp, Expression.Default(typeof(PropertyInfo)) })), Expression.Add(dataIndexExp, Expression.Constant(1)))) ), Expression.Label(returnTarget, Expression.Default(typeof(RowInfo))) @@ -1829,7 +1824,7 @@ namespace FreeSql.Internal var name = row2.GetName(a); //expando[name] = row2.GetValue(a); if (expandodic.ContainsKey(name)) continue; - expandodic.Add(name, Utils.InternalDataReaderGetValue(commonUtils2, row2, a)); + expandodic.Add(name, Utils.InternalDataReaderGetValue(commonUtils2, row2, a, null)); } //expando = expandodic; return new RowInfo(expandodic, fc); @@ -1864,9 +1859,10 @@ namespace FreeSql.Internal { if (typetb.ColumnsByCsIgnore.ContainsKey(ctorParm.Name)) continue; var readType = typetb.ColumnsByCs.TryGetValue(ctorParm.Name, out var trycol) ? trycol.Attribute.MapType : ctorParm.ParameterType; + var colprop = trycol != null ? typetb.Table.Properties[trycol.CsName] : null; var ispkExp = new List(); - Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp })); + Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp, Expression.Constant(colprop) })); Expression readExpAssign = null; //加速缓存 if (readType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor, GetDataReaderValueBlockExpression(readType, readpkvalExp), @@ -1882,7 +1878,7 @@ namespace FreeSql.Internal { //判断主键为空,则整个对象不读取 - //blockExp.Add(Expression.Assign(readpkvalExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp }))); + //blockExp.Add(Expression.Assign(readpkvalExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp, Expression.Constant(colprop) }))); if (trycol?.Attribute.IsPrimary == true) { ispkExp.Add( @@ -1985,7 +1981,7 @@ namespace FreeSql.Internal } var ispkExp = new List(); var propGetSetMethod = prop.GetSetMethod(true); - Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, tryidxExp })); + Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, tryidxExp, Expression.Constant(prop) })); Expression readExpAssign = null; //加速缓存 if (readType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor, GetDataReaderValueBlockExpression(readType, readpkvalExp), @@ -2001,7 +1997,7 @@ namespace FreeSql.Internal { //判断主键为空,则整个对象不读取 - //blockExp.Add(Expression.Assign(readpkvalExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp }))); + //blockExp.Add(Expression.Assign(readpkvalExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp, Expression.Constant(prop) }))); if (flagStr.StartsWith("adoQuery") == false && //Ado.Query 的时候不作此判断 trycol?.Attribute.IsPrimary == true) //若主键值为 null,则整行读取出来的对象为 null { @@ -2088,7 +2084,7 @@ namespace FreeSql.Internal indexes2 = ctor.GetParameters().Select(c => row2.GetOrdinal(c.Name)).ToArray(); for (var c = 0; c < ctorParms.Length; c++) - ctorParms[c] = Utils.InternalDataReaderGetValue(commonUtils2, row2, indexes2[c]); + ctorParms[c] = Utils.InternalDataReaderGetValue(commonUtils2, row2, indexes2[c], null); return new RowInfo(ctor.Invoke(ctorParms), ctorParms.Length); }