diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..5a0c8bd0 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -532,14 +525,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index 8faf37e7..78e554ef 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -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(); + + 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() { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index b588f700..c3f1bb5e 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2813,6 +2813,11 @@ Insert/Update自动值处理 + + + ADO.NET DataReader 拦截 + + 监视数据库命令对象(执行前,调试) @@ -2978,6 +2983,21 @@ 获取实体的属性值,也可以设置实体的属性新值 + + + ADO.NET 数据流读取对象 + + + + + DataReader 对应的 Index 位置 + + + + + 获取 Index 对应的值,也可以设置拦截的新值 + + 标识符,可将 CommandBefore 与 CommandAfter 进行匹配 diff --git a/FreeSql/Interface/IAop.cs b/FreeSql/Interface/IAop.cs index bef5f515..a3913c4d 100644 --- a/FreeSql/Interface/IAop.cs +++ b/FreeSql/Interface/IAop.cs @@ -57,6 +57,12 @@ namespace FreeSql event EventHandler AuditValue; EventHandler AuditValueHandler { get; } + /// + /// ADO.NET DataReader 拦截 + /// + event EventHandler AuditDataReader; + EventHandler AuditDataReaderHandler { get; } + /// /// 监视数据库命令对象(执行前,调试) /// @@ -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; + } + + /// + /// ADO.NET 数据流读取对象 + /// + public DbDataReader DataReader { get; } + /// + /// DataReader 对应的 Index 位置 + /// + public int Index { get; } + /// + /// 获取 Index 对应的值,也可以设置拦截的新值 + /// + 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 { diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 89c9e696..8c867350 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -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); diff --git a/FreeSql/Internal/CommonProvider/AopProvider.cs b/FreeSql/Internal/CommonProvider/AopProvider.cs index 1f426e04..648d29fe 100644 --- a/FreeSql/Internal/CommonProvider/AopProvider.cs +++ b/FreeSql/Internal/CommonProvider/AopProvider.cs @@ -18,6 +18,7 @@ namespace FreeSql.Internal.CommonProvider public event EventHandler SyncStructureAfter; public event EventHandler AuditValue; + public event EventHandler AuditDataReader; public event EventHandler CommandBefore; public event EventHandler CommandAfter; @@ -36,6 +37,7 @@ namespace FreeSql.Internal.CommonProvider public EventHandler SyncStructureAfterHandler => SyncStructureAfter; public EventHandler AuditValueHandler => AuditValue; + public EventHandler AuditDataReaderHandler => AuditDataReader; public EventHandler CommandBeforeHandler => CommandBefore; public EventHandler CommandAfterHandler => CommandAfter; diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index 61d2bcb3..4a2df3fc 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -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) diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 1dc8da61..30495e56 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -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) diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index a2b50eaa..63a46ea0 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -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) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 42b027d0..29e03050 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -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);