mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-06-20 04:48:16 +08:00
## v0.3.22
- 优化 导航属性 ManyToOne 名称查找规则; - 增加 IFreeSql.Aop 属性,未来所有拦截方法都在这里,第一期支持如下: * 监控 ToList 返回的的数据,用于拦截重新装饰; * 监视 Where,包括 select/update/delete,返回值 true 时可使上层不被执行; * 可自定义解析表达式; - 增加 ISelect.TractToList,用于单次跟踪或审核实体; - 优化 FreeSql.DbContext SaveChanges;
This commit is contained in:
@ -227,8 +227,13 @@ namespace FreeSql.Internal {
|
||||
static ConcurrentDictionary<Type, MethodInfo> _dicExpressionLambdaToSqlAsSelectAnyMethodInfo = new ConcurrentDictionary<Type, MethodInfo>();
|
||||
static ConcurrentDictionary<Type, PropertyInfo> _dicNullableValueProperty = new ConcurrentDictionary<Type, PropertyInfo>();
|
||||
static ConcurrentDictionary<Type, Expression> _dicFreeSqlGlobalExtensionsAsSelectExpression = new ConcurrentDictionary<Type, Expression>();
|
||||
internal string ExpressionLambdaToSql(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
|
||||
internal string ExpressionLambdaToSql(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDiyParse = true) {
|
||||
if (exp == null) return "";
|
||||
if (isDiyParse) {
|
||||
var args = new AopParseExpressionEventArgs(exp, ukexp => ExpressionLambdaToSql(exp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, false));
|
||||
_common._orm.Aop.ParseExpression?.Invoke(this, args);
|
||||
if (string.IsNullOrEmpty(args.Result) == false) return args.Result;
|
||||
}
|
||||
switch (exp.NodeType) {
|
||||
case ExpressionType.Not: return $"not({ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||
case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||
|
13
FreeSql/Internal/CommonProvider/AopProvider.cs
Normal file
13
FreeSql/Internal/CommonProvider/AopProvider.cs
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
class AopProvider : IAop {
|
||||
public EventHandler<AopToListEventArgs> ToList { get; set; }
|
||||
public EventHandler<AopWhereEventArgs> Where { get; set; }
|
||||
public EventHandler<AopParseExpressionEventArgs> ParseExpression { get; set; }
|
||||
}
|
||||
}
|
@ -51,6 +51,10 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
public IDelete<T1> Where(Expression<Func<T1, bool>> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, null, exp?.Body, null));
|
||||
public IDelete<T1> Where(string sql, object parms = null) {
|
||||
if (string.IsNullOrEmpty(sql)) return this;
|
||||
var args = new AopWhereEventArgs(sql, parms);
|
||||
_orm.Aop.Where?.Invoke(this, new AopWhereEventArgs(sql, parms));
|
||||
if (args.IsCancel == true) return this;
|
||||
|
||||
if (++_whereTimes > 1) _where.Append(" AND ");
|
||||
_where.Append("(").Append(sql).Append(")");
|
||||
if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms));
|
||||
|
@ -28,6 +28,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
protected CommonUtils _commonUtils;
|
||||
protected CommonExpression _commonExpression;
|
||||
protected DbTransaction _transaction;
|
||||
protected Action<object> _trackToList;
|
||||
|
||||
internal static void CopyData(Select0Provider<TSelect, T1> from, object to, ReadOnlyCollection<ParameterExpression> lambParms) {
|
||||
var toType = to?.GetType();
|
||||
@ -60,6 +61,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
//toType.GetField("_commonUtils", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._commonUtils);
|
||||
//toType.GetField("_commonExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._commonExpression);
|
||||
toType.GetField("_transaction", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._transaction);
|
||||
toType.GetField("_trackToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._trackToList);
|
||||
}
|
||||
|
||||
public Select0Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) {
|
||||
@ -71,6 +73,11 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure<T1>();
|
||||
}
|
||||
|
||||
public TSelect TrackToList(Action<object> track) {
|
||||
_trackToList = track;
|
||||
return this as TSelect;
|
||||
}
|
||||
|
||||
public TSelect WithTransaction(DbTransaction transaction) {
|
||||
_transaction = transaction;
|
||||
return this as TSelect;
|
||||
@ -215,6 +222,8 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
var read = Utils.ExecuteArrayRowReadClassOrTuple(type, null, dr, 0, _commonUtils);
|
||||
ret.Add((TTuple)read.Value);
|
||||
}, CommandType.Text, sql, _params.ToArray());
|
||||
_orm.Aop.ToList?.Invoke(this, new AopToListEventArgs(ret));
|
||||
_trackToList?.Invoke(ret);
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
@ -230,6 +239,8 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
ret.Add((TTuple)read.Value);
|
||||
return Task.CompletedTask;
|
||||
}, CommandType.Text, sql, _params.ToArray());
|
||||
_orm.Aop.ToList?.Invoke(this, new AopToListEventArgs(ret));
|
||||
_trackToList?.Invoke(ret);
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
@ -243,6 +254,8 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
_orm.Ado.ExecuteReader(_transaction, dr => {
|
||||
ret.Add(af.Read(dr));
|
||||
}, CommandType.Text, sql, _params.ToArray());
|
||||
_orm.Aop.ToList?.Invoke(this, new AopToListEventArgs(ret));
|
||||
_trackToList?.Invoke(ret);
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
@ -257,6 +270,8 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
ret.Add(af.Read(dr));
|
||||
return Task.CompletedTask;
|
||||
}, CommandType.Text, sql, _params.ToArray());
|
||||
_orm.Aop.ToList?.Invoke(this, new AopToListEventArgs(ret));
|
||||
_trackToList?.Invoke(ret);
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
@ -283,6 +298,8 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
var index = -1;
|
||||
ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false));
|
||||
}, CommandType.Text, sql, _params.ToArray());
|
||||
_orm.Aop.ToList?.Invoke(this, new AopToListEventArgs(ret));
|
||||
_trackToList?.Invoke(ret);
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
@ -298,6 +315,8 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false));
|
||||
return Task.CompletedTask;
|
||||
}, CommandType.Text, sql, _params.ToArray());
|
||||
_orm.Aop.ToList?.Invoke(this, new AopToListEventArgs(ret));
|
||||
_trackToList?.Invoke(ret);
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
@ -480,6 +499,10 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
public TSelect Where(string sql, object parms = null) => this.WhereIf(true, sql, parms);
|
||||
public TSelect WhereIf(bool condition, string sql, object parms = null) {
|
||||
if (condition == false || string.IsNullOrEmpty(sql)) return this as TSelect;
|
||||
var args = new AopWhereEventArgs(sql, parms);
|
||||
_orm.Aop.Where?.Invoke(this, new AopWhereEventArgs(sql, parms));
|
||||
if (args.IsCancel == true) return this as TSelect;
|
||||
|
||||
_where.Append(" AND (").Append(sql).Append(")");
|
||||
if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms));
|
||||
return this as TSelect;
|
||||
|
@ -79,7 +79,5 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) });
|
||||
return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -117,6 +117,10 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
public IUpdate<T1> Where(Expression<Func<T1, bool>> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, null, expression?.Body, null));
|
||||
public IUpdate<T1> Where(string sql, object parms = null) {
|
||||
if (string.IsNullOrEmpty(sql)) return this;
|
||||
var args = new AopWhereEventArgs(sql, parms);
|
||||
_orm.Aop.Where?.Invoke(this, new AopWhereEventArgs(sql, parms));
|
||||
if (args.IsCancel == true) return this;
|
||||
|
||||
_where.Append(" AND (").Append(sql).Append(")");
|
||||
if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms));
|
||||
return this;
|
||||
|
@ -494,7 +494,10 @@ namespace FreeSql.Internal {
|
||||
var findtbrefPkCsName = tbref.Primarys[a].CsName.TrimStart('_');
|
||||
if (findtbrefPkCsName.StartsWith(tbref.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtbrefPkCsName = findtbrefPkCsName.Substring(tbref.Type.Name.Length).TrimStart('_');
|
||||
if (trytb.ColumnsByCs.TryGetValue($"{pnv.Name}{findtbrefPkCsName}", out var trycol) == false && //骆峰命名
|
||||
trytb.ColumnsByCs.TryGetValue($"{pnv.Name}_{findtbrefPkCsName}", out trycol) == false //下划线命名
|
||||
trytb.ColumnsByCs.TryGetValue($"{pnv.Name}_{findtbrefPkCsName}", out trycol) == false && //下划线命名
|
||||
tbref.Primarys.Length == 1 &&
|
||||
trytb.ColumnsByCs.TryGetValue($"{pnv.Name}_Id", out trycol) == false &&
|
||||
trytb.ColumnsByCs.TryGetValue($"{pnv.Name}Id", out trycol) == false
|
||||
) {
|
||||
//一对一,主键与主键查找
|
||||
if (isOnoToOne) {
|
||||
|
Reference in New Issue
Block a user