private Statement PreStatement(Type interfaceType, SqlMap sqlMap, MethodInfo methodInfo, Type returnType, bool isTaskReturnType, out ExecuteBehavior executeBehavior) { var statementAttr = methodInfo.GetCustomAttribute <StatementAttribute>(); var methodName = _sqlIdNamingConvert == null ? methodInfo.Name : _sqlIdNamingConvert.Invoke(interfaceType, methodInfo); if (isTaskReturnType && methodInfo.Name.EndsWith("Async") && _sqlIdNamingConvert == null) { methodName = methodName.Substring(0, methodName.Length - 5); } if (statementAttr != null) { statementAttr.Id = !String.IsNullOrEmpty(statementAttr.Id) ? statementAttr.Id : methodName; } else { statementAttr = new StatementAttribute { Id = methodName }; } var fullSqlId = $"{sqlMap.Scope}.{statementAttr.Id}"; Statement statement; if (String.IsNullOrEmpty(statementAttr.Sql)) { statement = sqlMap.GetStatement(fullSqlId); } else { if (sqlMap.Statements.ContainsKey(fullSqlId)) { throw new SmartSqlException($"Statement.FullSqlId:[{fullSqlId}] already exists!"); } var resultCacheAttr = methodInfo.GetCustomAttribute <ResultCacheAttribute>(); statement = new Statement { SqlMap = sqlMap, Id = statementAttr.Id, StatementType = _statementAnalyzer.Analyse(statementAttr.Sql), SqlTags = new List <ITag> { new SqlText(statementAttr.Sql, sqlMap.SmartSqlConfig.Database.DbProvider.ParameterPrefix) }, CommandType = statementAttr.CommandType, EnablePropertyChangedTrack = statementAttr.EnablePropertyChangedTrack, ReadDb = statementAttr.ReadDb }; if (statementAttr.CommandTimeout > 0) { statement.CommandTimeout = statementAttr.CommandTimeout; } if (statementAttr.SourceChoice != DataSourceChoice.Unknow) { statement.SourceChoice = statementAttr.SourceChoice; } if (resultCacheAttr != null) { statement.CacheId = ParseCacheFullId(sqlMap.Scope, resultCacheAttr.CacheId); statement.Cache = sqlMap.GetCache(statement.CacheId); } sqlMap.Statements.Add(statement.FullSqlId, statement); } returnType = isTaskReturnType ? returnType.GetGenericArguments().FirstOrDefault() : returnType; if (returnType == typeof(DataTable)) { statementAttr.Execute = ExecuteBehavior.GetDataTable; } if (returnType == typeof(DataSet)) { statementAttr.Execute = ExecuteBehavior.GetDataSet; } if (statementAttr.Execute == ExecuteBehavior.Auto) { if (CommonType.IsValueTuple(returnType)) { statementAttr.Execute = ExecuteBehavior.QuerySingle; } else if (returnType == CommonType.Int32 || returnType == CommonType.Void || returnType == null) { statementAttr.Execute = ExecuteBehavior.Execute; if (returnType == CommonType.Int32) { if (statement.StatementType.HasFlag(Configuration.StatementType.Select)) { statementAttr.Execute = ExecuteBehavior.ExecuteScalar; } } } else if (returnType.IsValueType || returnType == CommonType.String) { statementAttr.Execute = ExecuteBehavior.ExecuteScalar; if (!statement.StatementType.HasFlag(Configuration.StatementType.Select)) { statementAttr.Execute = ExecuteBehavior.Execute; } } else { var isQueryEnumerable = typeof(IEnumerable).IsAssignableFrom(returnType); statementAttr.Execute = isQueryEnumerable ? ExecuteBehavior.Query : ExecuteBehavior.QuerySingle; } } executeBehavior = statementAttr.Execute; return(statement); }
private MethodInfo PreExecuteMethod(ExecuteBehavior executeBehavior, Type returnType, bool isTaskReturnType) { MethodInfo executeMethod; if (isTaskReturnType) { var realReturnType = returnType.GenericTypeArguments.FirstOrDefault(); switch (executeBehavior) { case ExecuteBehavior.Execute: { executeMethod = ISqlMapperType.Method.ExecuteAsync; break; } case ExecuteBehavior.ExecuteScalar: { executeMethod = ISqlMapperType.Method.ExecuteScalarAsync.MakeGenericMethod(realReturnType); break; } case ExecuteBehavior.QuerySingle: { executeMethod = ISqlMapperType.Method.QuerySingleAsync.MakeGenericMethod(realReturnType); break; } case ExecuteBehavior.Query: { var method = ISqlMapperType.Method.QueryAsync; var enumerableType = realReturnType.GenericTypeArguments[0]; executeMethod = method.MakeGenericMethod(enumerableType); break; } case ExecuteBehavior.GetDataTable: { executeMethod = ISqlMapperType.Method.GetDataTableAsync; break; } case ExecuteBehavior.GetDataSet: { executeMethod = ISqlMapperType.Method.GetDataSetAsync; break; } default: { throw new ArgumentException(); } } } else { switch (executeBehavior) { case ExecuteBehavior.Execute: { executeMethod = ISqlMapperType.Method.Execute; break; } case ExecuteBehavior.ExecuteScalar: { executeMethod = ISqlMapperType.Method.ExecuteScalar.MakeGenericMethod(returnType); break; } case ExecuteBehavior.QuerySingle: { executeMethod = ISqlMapperType.Method.QuerySingle.MakeGenericMethod(returnType); break; } case ExecuteBehavior.Query: { var method = ISqlMapperType.Method.Query; var enumerableType = returnType.GenericTypeArguments[0]; executeMethod = method.MakeGenericMethod(new Type[] { enumerableType }); break; } case ExecuteBehavior.GetDataTable: { executeMethod = ISqlMapperType.Method.GetDataTable; break; } case ExecuteBehavior.GetDataSet: { executeMethod = ISqlMapperType.Method.GetDataSet; break; } default: { throw new ArgumentException(); } } } return(executeMethod); }
private Expression VisitExecuteMethodCall(MethodCallExpression node) { switch (node.Method.Name) { case MethodCall.From: var value = (Func <ITableRegions, string>)node.Arguments[1].GetValueFromExpression(); if (value == null) { throw new DException("指定表名称不能为空!"); } SetTableFactory(value); base.Visit(node.Arguments[0]); return(node); case MethodCall.Where: if (Behavior == ExecuteBehavior.Insert) { throw new ExpressionNotSupportedException("插入语句不支持条件,请在查询器中使用条件过滤!"); } return(MakeWhereNode(node)); case MethodCall.Update: Behavior = ExecuteBehavior.Update; base.Visit(node.Arguments[0]); SQLWriter.AppendAt = 0; SQLWriter.Update(); SQLWriter.Alias(GetOrAddTablePrefix(typeof(T))); SQLWriter.Set(); base.Visit(node.Arguments[1]); SQLWriter.From(); WriteTable(typeof(T)); SQLWriter.AppendAt = -1; return(node); case MethodCall.Delete: Behavior = ExecuteBehavior.Delete; base.Visit(node.Arguments[0]); SQLWriter.AppendAt = 0; SQLWriter.Delete(); SQLWriter.Alias(GetOrAddTablePrefix(typeof(T))); SQLWriter.From(); WriteTable(typeof(T)); SQLWriter.AppendAt = -1; return(node); case MethodCall.Insert: Behavior = ExecuteBehavior.Insert; base.Visit(node.Arguments[0]); SQLWriter.AppendAt = 0; SQLWriter.Insert(); WriteTable(typeof(T)); SQLWriter.AppendAt = -1; VisitBuilder(node.Arguments[1]); return(node); } throw new ExpressionNotSupportedException(); }