diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml
index d9f91124..dc0203b8 100644
--- a/FreeSql.DbContext/FreeSql.DbContext.xml
+++ b/FreeSql.DbContext/FreeSql.DbContext.xml
@@ -110,13 +110,6 @@
清空状态数据
-
-
- 根据 lambda 条件删除数据
-
-
-
-
添加
diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs
index 82594730..d97e28fc 100644
--- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs
+++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs
@@ -13,6 +13,7 @@ using System.ComponentModel.DataAnnotations;
using System.Threading;
using System.Data.SqlClient;
using kwlib;
+using System.Text;
namespace FreeSql.Tests
{
diff --git a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs
index 4342ff13..6970eca9 100644
--- a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs
+++ b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs
@@ -1,6 +1,9 @@
-using System;
+using FreeSql.Internal;
+using FreeSql.Internal.Model;
+using System;
using System.Collections.Generic;
using System.Data.Common;
+using System.Linq.Expressions;
using System.Text;
namespace FreeSql.DataAnnotations
@@ -23,6 +26,15 @@ namespace FreeSql.DataAnnotations
public class ExpressionCallContext
{
+ internal ExpressionCallContext()
+ {
+ Utility = new DefaultUtility { _context = this };
+ }
+
+ public IUtility Utility { get; }
+
+ internal CommonExpression _commonExp;
+ internal CommonExpression.ExpTSC _tsc;
///
/// 数据库类型,可用于适配多种数据库环境
///
@@ -32,6 +44,10 @@ namespace FreeSql.DataAnnotations
/// 已解析的表达式中参数内容
///
public Dictionary ParsedContent { get; } = new Dictionary();
+ ///
+ /// 表达式原始值
+ ///
+ public Dictionary RawExpression { get; } = new Dictionary();
///
/// 主对象的参数化对象,可重塑其属性
@@ -53,5 +69,31 @@ namespace FreeSql.DataAnnotations
/// 返回表达式函数表示的 SQL 字符串
///
public string Result { get; set; }
+
+ public interface IUtility
+ {
+ ///
+ /// 获取实体元数据
+ ///
+ ///
+ ///
+ TableInfo GetTableByEntity(Type entityType);
+
+ ///
+ /// 解析表达式
+ ///
+ ///
+ ///
+ string ParseExpression(Expression exp);
+ }
+
+ class DefaultUtility : IUtility
+ {
+ internal ExpressionCallContext _context;
+
+ public TableInfo GetTableByEntity(Type entityType) => _context?._commonExp._common.GetTableByEntity(entityType);
+
+ public string ParseExpression(Expression exp) => _context?._commonExp.ExpressionLambdaToSql(exp, _context._tsc.CloneDisableDiyParse());
+ }
}
}
diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml
index b6056f16..13ec6385 100644
--- a/FreeSql/FreeSql.xml
+++ b/FreeSql/FreeSql.xml
@@ -219,6 +219,11 @@
已解析的表达式中参数内容
+
+
+ 表达式原始值
+
+
主对象的参数化对象,可重塑其属性
@@ -240,6 +245,20 @@
返回表达式函数表示的 SQL 字符串
+
+
+ 获取实体元数据
+
+
+
+
+
+
+ 解析表达式
+
+
+
+
索引名
@@ -2205,6 +2224,137 @@
+
+
+ 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
+
+
+
+
+
+
+
+
+ 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 })
+
+
+
+
+
+
+ 查询
+
+
+
+
+
+
+ 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 })
+
+
+
+
+
+
+
+ 查询
+
+
+
+
+
+
+ 查询,ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 })
+
+
+
+
+
+
+
+ 查询
+
+
+
+
+
+
+ 查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 })
+
+
+
+
+
+
+
+ 在【主库】执行
+
+
+
+
+
+
+
+ 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 })
+
+
+
+
+
+
+
+ 在【主库】执行
+
+
+
+
+
+
+
+ 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 })
+
+
+
+
+
+
+
+ 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 })
+
+
+
+
+
+
+
+
+
+ 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new { age = 25 })
+
+
+
+
+
+
+
+
+ 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 })
+
+
+
+
+
+
+
+
+
+ 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new { age = 25 })
+
+
+
+
+
+
可自定义解析表达式
diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs
index 1d68f397..a6beb913 100644
--- a/FreeSql/Internal/CommonExpression.cs
+++ b/FreeSql/Internal/CommonExpression.cs
@@ -602,15 +602,25 @@ namespace FreeSql.Internal
exp3.Method.GetCustomAttributes(typeof(ExpressionCallAttribute), true).Any()
))
{
- var ecc = new ExpressionCallContext { DataType = _ado.DataType, UserParameters = tsc.dbParams == null ? null : new List(), FormatSql = obj => formatSql(obj, null, null, null) };
+ var ecc = new ExpressionCallContext {
+ _commonExp = this,
+ _tsc = tsc,
+ DataType = _ado.DataType,
+ UserParameters = tsc.dbParams == null ? null : new List(),
+ FormatSql = obj => formatSql(obj, null, null, null)
+ };
var exp3MethodParams = exp3.Method.GetParameters();
var dbParamsIndex = tsc.dbParams?.Count;
- ecc.ParsedContent.Add(exp3MethodParams[0].Name, exp3MethodParams[0].GetCustomAttributes(typeof(RawValueAttribute), true).Any() ? null: ExpressionLambdaToSql(exp3.Arguments[0], tsc));
+ ecc.RawExpression.Add(exp3MethodParams[0].Name, exp3.Arguments[0]);
+ ecc.ParsedContent.Add(exp3MethodParams[0].Name, exp3MethodParams[0].GetCustomAttributes(typeof(RawValueAttribute), true).Any() ? null : ExpressionLambdaToSql(exp3.Arguments[0], tsc));
if (tsc.dbParams?.Count > dbParamsIndex) ecc.DbParameter = tsc.dbParams.Last();
List oldDbParams = tsc.SetDbParamsReturnOld(null);
for (var a = 1; a < exp3.Arguments.Count; a++)
if (exp3.Arguments[a].Type != typeof(ExpressionCallContext))
+ {
+ ecc.RawExpression.Add(exp3MethodParams[a].Name, exp3.Arguments[a]);
ecc.ParsedContent.Add(exp3MethodParams[a].Name, exp3MethodParams[a].GetCustomAttributes(typeof(RawValueAttribute), true).Any() ? null : ExpressionLambdaToSql(exp3.Arguments[a], tsc));
+ }
tsc.SetDbParamsReturnOld(oldDbParams);
var exp3InvokeParams = new object[exp3.Arguments.Count];
diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs
index 3c0e3054..11299db6 100644
--- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs
+++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs
@@ -78,7 +78,7 @@ namespace FreeSql.Internal.CommonProvider
cmd.Parameters.Clear();
if (isThrowException)
{
- cmd.Dispose();
+ if (DataType == DataType.Sqlite) cmd.Dispose();
throw e;
}
}
@@ -575,7 +575,7 @@ namespace FreeSql.Internal.CommonProvider
}
LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false);
pc.cmd.Parameters.Clear();
- pc.cmd.Dispose();
+ if (DataType == DataType.Sqlite) pc.cmd.Dispose();
ExecuteReaderMultiple(multipleResult, connection, transaction, readerHander, cmdType, cmdText, cmdParms);
return;
}
@@ -638,7 +638,7 @@ namespace FreeSql.Internal.CommonProvider
}
LoggerException(pool, pc, ex, dt, logtxt);
pc.cmd.Parameters.Clear();
- pc.cmd.Dispose();
+ if (DataType == DataType.Sqlite) pc.cmd.Dispose();
}
public object[][] ExecuteArray(string cmdText, object parms = null) => ExecuteArray(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
public object[][] ExecuteArray(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArray(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
@@ -739,7 +739,7 @@ namespace FreeSql.Internal.CommonProvider
}
LoggerException(this.MasterPool, pc, ex, dt, logtxt);
pc.cmd.Parameters.Clear();
- pc.cmd.Dispose();
+ if (DataType == DataType.Sqlite) pc.cmd.Dispose();
return val;
}
public object ExecuteScalar(string cmdText, object parms = null) => ExecuteScalar(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
@@ -775,7 +775,7 @@ namespace FreeSql.Internal.CommonProvider
}
LoggerException(this.MasterPool, pc, ex, dt, logtxt);
pc.cmd.Parameters.Clear();
- pc.cmd.Dispose();
+ if (DataType == DataType.Sqlite) pc.cmd.Dispose();
return val;
}
diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs
index efe6cd71..694ac18c 100644
--- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs
+++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs
@@ -504,7 +504,7 @@ namespace FreeSql.Internal.CommonProvider
}
LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false);
pc.cmd.Parameters.Clear();
- pc.cmd.Dispose();
+ if (DataType == DataType.Sqlite) pc.cmd.Dispose();
await ExecuteReaderMultipleAsync(multipleResult, connection, transaction, readerHander, cmdType, cmdText, cmdParms);
return;
}
@@ -567,7 +567,7 @@ namespace FreeSql.Internal.CommonProvider
}
LoggerException(pool, pc, ex, dt, logtxt);
pc.cmd.Parameters.Clear();
- pc.cmd.Dispose();
+ if (DataType == DataType.Sqlite) pc.cmd.Dispose();
}
public Task