Skip to content

Commit

Permalink
- 完善 ExpressionCall 方法;
Browse files Browse the repository at this point in the history
  • Loading branch information
28810 authored and 28810 committed Dec 25, 2019
1 parent ea7a860 commit a664bc4
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 19 deletions.
7 changes: 0 additions & 7 deletions FreeSql.DbContext/FreeSql.DbContext.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions FreeSql.Tests/FreeSql.Tests/UnitTest2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.Threading;
using System.Data.SqlClient;
using kwlib;
using System.Text;

namespace FreeSql.Tests
{
Expand Down
44 changes: 43 additions & 1 deletion FreeSql/DataAnnotations/ExpressionCallAttribute.cs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -23,6 +26,15 @@ public class RawValueAttribute : Attribute

public class ExpressionCallContext
{
internal ExpressionCallContext()
{
Utility = new DefaultUtility { _context = this };
}

public IUtility Utility { get; }

internal CommonExpression _commonExp;
internal CommonExpression.ExpTSC _tsc;
/// <summary>
/// 数据库类型,可用于适配多种数据库环境
/// </summary>
Expand All @@ -32,6 +44,10 @@ public class ExpressionCallContext
/// 已解析的表达式中参数内容
/// </summary>
public Dictionary<string, string> ParsedContent { get; } = new Dictionary<string, string>();
/// <summary>
/// 表达式原始值
/// </summary>
public Dictionary<string, Expression> RawExpression { get; } = new Dictionary<string, Expression>();

/// <summary>
/// 主对象的参数化对象,可重塑其属性
Expand All @@ -53,5 +69,31 @@ public class ExpressionCallContext
/// 返回表达式函数表示的 SQL 字符串
/// </summary>
public string Result { get; set; }

public interface IUtility
{
/// <summary>
/// 获取实体元数据
/// </summary>
/// <param name="entityType"></param>
/// <returns></returns>
TableInfo GetTableByEntity(Type entityType);

/// <summary>
/// 解析表达式
/// </summary>
/// <param name="exp"></param>
/// <returns></returns>
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());
}
}
}
150 changes: 150 additions & 0 deletions FreeSql/FreeSql.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 12 additions & 2 deletions FreeSql/Internal/CommonExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -602,15 +602,25 @@ public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc)
exp3.Method.GetCustomAttributes(typeof(ExpressionCallAttribute), true).Any()
))
{
var ecc = new ExpressionCallContext { DataType = _ado.DataType, UserParameters = tsc.dbParams == null ? null : new List<DbParameter>(), 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<DbParameter>(),
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<DbParameter> 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];
Expand Down
10 changes: 5 additions & 5 deletions FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void LoggerException(IObjectPool<DbConnection> pool, (DbCommand cmd, bool isclos
cmd.Parameters.Clear();
if (isThrowException)
{
cmd.Dispose();
if (DataType == DataType.Sqlite) cmd.Dispose();
throw e;
}
}
Expand Down Expand Up @@ -575,7 +575,7 @@ void ExecuteReaderMultiple(int multipleResult, DbConnection connection, DbTransa
}
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;
}
Expand Down Expand Up @@ -638,7 +638,7 @@ void ExecuteReaderMultiple(int multipleResult, DbConnection connection, DbTransa
}
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));
Expand Down Expand Up @@ -739,7 +739,7 @@ public int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, C
}
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));
Expand Down Expand Up @@ -775,7 +775,7 @@ public object ExecuteScalar(DbConnection connection, DbTransaction transaction,
}
LoggerException(this.MasterPool, pc, ex, dt, logtxt);
pc.cmd.Parameters.Clear();
pc.cmd.Dispose();
if (DataType == DataType.Sqlite) pc.cmd.Dispose();
return val;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connectio
}
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;
}
Expand Down Expand Up @@ -567,7 +567,7 @@ async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connectio
}
LoggerException(pool, pc, ex, dt, logtxt);
pc.cmd.Parameters.Clear();
pc.cmd.Dispose();
if (DataType == DataType.Sqlite) pc.cmd.Dispose();
}
public Task<object[][]> ExecuteArrayAsync(string cmdText, object parms = null) => ExecuteArrayAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
public Task<object[][]> ExecuteArrayAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArrayAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
Expand Down Expand Up @@ -669,7 +669,7 @@ async public Task<int> ExecuteNonQueryAsync(DbConnection connection, DbTransacti
}
LoggerException(this.MasterPool, pc, ex, dt, logtxt);
pc.cmd.Parameters.Clear();
pc.cmd.Dispose();
if (DataType == DataType.Sqlite) pc.cmd.Dispose();
return val;
}
public Task<object> ExecuteScalarAsync(string cmdText, object parms = null) => ExecuteScalarAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
Expand Down Expand Up @@ -705,7 +705,7 @@ async public Task<object> ExecuteScalarAsync(DbConnection connection, DbTransact
}
LoggerException(this.MasterPool, pc, ex, dt, logtxt);
pc.cmd.Parameters.Clear();
pc.cmd.Dispose();
if (DataType == DataType.Sqlite) pc.cmd.Dispose();
return val;
}

Expand Down

0 comments on commit a664bc4

Please sign in to comment.