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);