- 增加 Aop.AuditDataReader 事件拦截 DataReader 读取值 #436;

This commit is contained in:
28810 2020-08-25 12:42:58 +08:00
parent 824d60cbb2
commit fbf62b6630
10 changed files with 136 additions and 26 deletions

View File

@ -130,13 +130,6 @@
清空状态数据
</summary>
</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)">
<summary>
添加
@ -532,14 +525,5 @@
<param name="that"></param>
<returns></returns>
</member>
<member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
<summary>
批量注入 Repository可以参考代码自行调整
</summary>
<param name="services"></param>
<param name="globalDataFilter"></param>
<param name="assemblies"></param>
<returns></returns>
</member>
</members>
</doc>

View File

@ -4,15 +4,62 @@ using Oracle.ManagedDataAccess.Client;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using Xunit;
namespace FreeSql.Tests.Oracle
{
public class OracleCodeFirstTest
{
[Fact]
public void StringNullToEmpty()
{
using (var fsql = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.Oracle, "user id=1user;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=5;min pool size=1")
.UseAutoSyncStructure(true)
//.UseGenerateCommandParameterWithLambda(true)
.UseLazyLoading(true)
.UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper)
//.UseNoneCommandParameter(true)
.UseMonitorCommand(
cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象在执行前
//, (cmd, traceLog) => Console.WriteLine(traceLog)
)
.Build())
{
var repo = fsql.GetRepository<TS_SL361, long>();
var item1 = new TS_SL361 { CreatorId = "" };
repo.Insert(item1);
var item2 = repo.Get(item1.Id);
Assert.Null(item2.CreatorId);
fsql.Aop.AuditDataReader += (_, e) =>
{
if (e.DataReader.GetFieldType(e.Index) == typeof(string) && e.Value == DBNull.Value)
e.Value = "";
};
item1 = new TS_SL361 { CreatorId = "" };
repo.Insert(item1);
item2 = repo.Get(item1.Id);
Assert.Equal(item1.CreatorId, item2.CreatorId);
}
}
class TS_SNTE
{
[Column(IsIdentity = true)]
public long Id { get; set; }
public string CreatorId { get; set; }
}
[Fact]
public void StringLength36()
{

View File

@ -2813,6 +2813,11 @@
Insert/Update自动值处理
</summary>
</member>
<member name="E:FreeSql.IAop.AuditDataReader">
<summary>
ADO.NET DataReader 拦截
</summary>
</member>
<member name="E:FreeSql.IAop.CommandBefore">
<summary>
监视数据库命令对象(执行前,调试)
@ -2978,6 +2983,21 @@
获取实体的属性值,也可以设置实体的属性新值
</summary>
</member>
<member name="P:FreeSql.Aop.AuditDataReaderEventArgs.DataReader">
<summary>
ADO.NET 数据流读取对象
</summary>
</member>
<member name="P:FreeSql.Aop.AuditDataReaderEventArgs.Index">
<summary>
DataReader 对应的 Index 位置
</summary>
</member>
<member name="P:FreeSql.Aop.AuditDataReaderEventArgs.Value">
<summary>
获取 Index 对应的值,也可以设置拦截的新值
</summary>
</member>
<member name="P:FreeSql.Aop.CommandBeforeEventArgs.Identifier">
<summary>
标识符,可将 CommandBefore 与 CommandAfter 进行匹配

View File

@ -57,6 +57,12 @@ namespace FreeSql
event EventHandler<Aop.AuditValueEventArgs> AuditValue;
EventHandler<Aop.AuditValueEventArgs> AuditValueHandler { get; }
/// <summary>
/// ADO.NET DataReader 拦截
/// </summary>
event EventHandler<Aop.AuditDataReaderEventArgs> AuditDataReader;
EventHandler<Aop.AuditDataReaderEventArgs> AuditDataReaderHandler { get; }
/// <summary>
/// 监视数据库命令对象(执行前,调试)
/// </summary>
@ -318,15 +324,59 @@ namespace FreeSql.Aop
set
{
_value = value;
this.IsChanged = true;
this.ValueIsChanged = true;
}
}
private object _value;
public bool IsChanged { get; private set; }
public bool ValueIsChanged { get; private set; }
}
public enum AuditValueType { Update, Insert, InsertOrUpdate }
#endregion
#region AuditDataReader
public class AuditDataReaderEventArgs : EventArgs
{
public AuditDataReaderEventArgs(DbDataReader dataReader, int index)
{
this.DataReader = dataReader;
this.Index = index;
}
/// <summary>
/// ADO.NET 数据流读取对象
/// </summary>
public DbDataReader DataReader { get; }
/// <summary>
/// DataReader 对应的 Index 位置
/// </summary>
public int Index { get; }
/// <summary>
/// 获取 Index 对应的值,也可以设置拦截的新值
/// </summary>
public object Value
{
get
{
if (_valueIsGeted == false)
{
_value = DataReader.GetValue(Index);
_valueIsGeted = true;
}
return _value;
}
set
{
_value = value;
ValueIsChanged = true;
_valueIsGeted = true;
}
}
private object _value;
internal bool _valueIsGeted;
public bool ValueIsChanged { get; private set; }
}
#endregion
#region CommandBefore/After
public class CommandBeforeEventArgs : EventArgs
{

View File

@ -309,7 +309,7 @@ namespace FreeSql.Internal
return Utils.GetDataReaderValue(parent.Property.PropertyType, null);
return Utils.GetDataReaderValue(parent.CsType, null);
}
object objval = dr.GetValue(++index);
object objval = Utils.InternalDataReaderGetValue(_common, dr, ++index); // dr.GetValue(++index);
if (dbValue != null) dbValue.DbValue = objval == DBNull.Value ? null : objval;
if (parent.CsType != parent.MapType)
objval = Utils.GetDataReaderValue(parent.MapType, objval);

View File

@ -18,6 +18,7 @@ namespace FreeSql.Internal.CommonProvider
public event EventHandler<Aop.SyncStructureAfterEventArgs> SyncStructureAfter;
public event EventHandler<Aop.AuditValueEventArgs> AuditValue;
public event EventHandler<Aop.AuditDataReaderEventArgs> AuditDataReader;
public event EventHandler<Aop.CommandBeforeEventArgs> CommandBefore;
public event EventHandler<Aop.CommandAfterEventArgs> CommandAfter;
@ -36,6 +37,7 @@ namespace FreeSql.Internal.CommonProvider
public EventHandler<Aop.SyncStructureAfterEventArgs> SyncStructureAfterHandler => SyncStructureAfter;
public EventHandler<Aop.AuditValueEventArgs> AuditValueHandler => AuditValue;
public EventHandler<Aop.AuditDataReaderEventArgs> AuditDataReaderHandler => AuditDataReader;
public EventHandler<Aop.CommandBeforeEventArgs> CommandBeforeHandler => CommandBefore;
public EventHandler<Aop.CommandAfterEventArgs> CommandAfterHandler => CommandAfter;

View File

@ -81,7 +81,7 @@ namespace FreeSql.Internal.CommonProvider
object val = col.GetValue(d);
var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.InsertOrUpdate, col, table.Properties[col.CsName], val);
orm.Aop.AuditValueHandler(sender, auditArgs);
if (auditArgs.IsChanged)
if (auditArgs.ValueIsChanged)
{
col.SetValue(d, val = auditArgs.Value);
if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false)
@ -101,7 +101,7 @@ namespace FreeSql.Internal.CommonProvider
object val = col.GetValue(data);
var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.InsertOrUpdate, col, table.Properties[col.CsName], val);
orm.Aop.AuditValueHandler(sender, auditArgs);
if (auditArgs.IsChanged)
if (auditArgs.ValueIsChanged)
{
col.SetValue(data, val = auditArgs.Value);
if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false)

View File

@ -152,7 +152,7 @@ namespace FreeSql.Internal.CommonProvider
{
var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Insert, col, table.Properties[col.CsName], val);
orm.Aop.AuditValueHandler(sender, auditArgs);
if (auditArgs.IsChanged)
if (auditArgs.ValueIsChanged)
{
col.SetValue(data, val = auditArgs.Value);
if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false)

View File

@ -353,7 +353,7 @@ namespace FreeSql.Internal.CommonProvider
object val = col.GetValue(d);
var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Update, col, table.Properties[col.CsName], val);
orm.Aop.AuditValueHandler(sender, auditArgs);
if (auditArgs.IsChanged)
if (auditArgs.ValueIsChanged)
{
col.SetValue(d, val = auditArgs.Value);
if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false)
@ -373,7 +373,7 @@ namespace FreeSql.Internal.CommonProvider
object val = col.GetValue(data);
var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Update, col, table.Properties[col.CsName], val);
orm.Aop.AuditValueHandler(sender, auditArgs);
if (auditArgs.IsChanged)
if (auditArgs.ValueIsChanged)
{
col.SetValue(data, val = auditArgs.Value);
if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false)

View File

@ -1324,7 +1324,14 @@ namespace FreeSql.Internal
internal static PropertyInfo PropertyDataReaderFieldCount = typeof(DbDataReader).GetProperty("FieldCount");
internal static object InternalDataReaderGetValue(CommonUtils commonUtil, DbDataReader dr, int index)
{
if (commonUtil._orm.Ado.DataType == DataType.Dameng && dr.IsDBNull(index)) return null;
var orm = commonUtil._orm;
if (orm.Aop.AuditDataReaderHandler != null)
{
var args = new Aop.AuditDataReaderEventArgs(dr, index);
orm.Aop.AuditDataReaderHandler(orm, args);
return args.Value;
}
if (orm.Ado.DataType == DataType.Dameng && dr.IsDBNull(index)) return null; //OdbcDameng 不会报错
return dr.GetValue(index);
}
internal static RowInfo ExecuteArrayRowReadClassOrTuple(string flagStr, Type typeOrg, int[] indexes, DbDataReader row, int dataIndex, CommonUtils _commonUtils)
@ -1447,7 +1454,7 @@ namespace FreeSql.Internal
var name = row2.GetName(a);
//expando[name] = row2.GetValue(a);
if (expandodic.ContainsKey(name)) continue;
expandodic.Add(name, row2.GetValue(a));
expandodic.Add(name, Utils.InternalDataReaderGetValue(_commonUtils, row2, a));
}
//expando = expandodic;
return new RowInfo(expandodic, fc);