/// <summary> /// 访问 IDbQueryable.Contains 方法 /// </summary> /// <param name="m">字段或属性表达式</param> protected override Expression VisitQueryableContains(MethodCallExpression m) { ITranslateContext context = _builder.TranslateContext; DbQueryable subquery = m.Arguments[0].Evaluate().Value as DbQueryable; subquery.Parameterized = _builder.Parameterized; // 可能会有几级嵌套,这里用 Builder.Ident 标记是第几层级 string[] subs = new[] { "p", "u", "v", "w", "x" }; var newContext = context != null?TranslateContext.Copy(context, subs[_builder.Indent]) : null; bool isDelete = context != null && ((SQLiteTranslateContext)context).IsDelete; var cmd = subquery.Translate(_builder.Indent + 1, false, newContext) as DbSelectCommand; if (this.NotOperands != null && this.NotOperands.Contains(m)) { _builder.Append("NOT "); } _builder.Append("EXISTS("); _builder.Append(cmd.CommandText); if (((DbSelectCommand)cmd).WhereFragment.Length > 0) { _builder.Append(" AND "); } else { _builder.Append("WHERE "); } _builder.Append(cmd.SelectedColumnText); _builder.Append(" = "); // exists 不能用别名 if (isDelete) { var typeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(((MemberExpression)m.Arguments[1]).Expression.Type); _builder.AppendTable(typeRuntime.TableSchema, typeRuntime.TableName, typeRuntime.IsTemporary); _builder.Append('.'); } _visitor.Visit(m.Arguments[1]); _builder.Append(")"); return(m); }
/// <summary> /// 解析 SQL 命令 /// <para> /// 返回的已经解析语义中执行批次用 null 分开 /// </para> /// </summary> /// <param name="dbQueryables">查询语句</param> /// <returns></returns> public override List <DbRawCommand> Translate(List <object> dbQueryables) { bool haveBegin = false; ITranslateContext context = null; var sqlList = new List <DbRawCommand>(); for (int i = 0; i < dbQueryables.Count; i++) { object obj = dbQueryables[i]; if (obj == null) { continue; } if (obj is IDbQueryable) { DbQueryable dbQuery = (DbQueryable)obj; dbQuery.Parameterized = true; if (context == null) { context = this.CreateTranslateContext(dbQuery.DbContext); } if (context.Parameters == null) { context.Parameters = new List <IDbDataParameter>(8); } var cmd = dbQuery.Translate(0, true, context); if (cmd is DbSelectCommand) { // 查询单独执行 if (sqlList.Count > 0 && (i - 1) >= 0 && sqlList[sqlList.Count - 1] != null) { sqlList.Add(null); } sqlList.Add(cmd); sqlList.Add(null); context = this.CreateTranslateContext(dbQuery.DbContext); context.Parameters = new List <IDbDataParameter>(8); } else { // 增删改 if (!haveBegin) { sqlList.Add(new DbRawCommand("BEGIN")); haveBegin = true; } sqlList.Add(cmd); if (cmd.Parameters != null && cmd.Parameters.Count > 1000) { // 1000个参数,就要重新分批 if (haveBegin) { sqlList.Add(new DbRawCommand("END;")); haveBegin = false; sqlList.Add(null); } context = this.CreateTranslateContext(dbQuery.DbContext); context.Parameters = new List <IDbDataParameter>(8); } if (i + 1 < dbQueryables.Count) { // 检查下一条是否是选择语句 bool isQuery = false; if (dbQueryables[i + 1] is IDbQueryable) { var tree = ((DbQueryable)dbQueryables[i + 1]).Parse(); isQuery = tree is DbQuerySelectTree; } else if ((dbQueryables[i + 1] is string)) { string sql = dbQueryables[i + 1].ToString(); string method = string.Empty; if (sql.Length > 6) { method = sql.Substring(0, 6).Trim().ToUpper(); } isQuery = method == "SELECT"; } else if (dbQueryables[i + 1] is DbRawSql) { string sql = ((DbRawSql)dbQueryables[i + 1]).CommandText; string method = string.Empty; if (sql.Length > 6) { method = sql.Substring(0, 6).Trim().ToUpper(); } isQuery = method == "SELECT"; } // 如果下一条是SELECT 语句,则需要结束当前语句块 if (isQuery) { if (haveBegin) { sqlList.Add(new DbRawCommand("END;")); haveBegin = false; sqlList.Add(null); } context = this.CreateTranslateContext(dbQuery.DbContext); context.Parameters = new List <IDbDataParameter>(8); } } } } else if (obj is DbRawSql || obj is string) { string sql = string.Empty; if (obj is string) { sql = obj.ToString(); } else { DbRawSql rawSql = (DbRawSql)obj; // 解析参数 object[] args = null; if (rawSql.Parameters != null) { args = rawSql.Parameters.Select(x => this.Constor.GetSqlValue(x, context)).ToArray(); } sql = rawSql.CommandText; if (args != null && args.Length > 0) { sql = string.Format(sql, args); } } string methodName = string.Empty; if (sql.Length > 6) { methodName = sql.Substring(0, 6).Trim().ToUpper(); } if (methodName == "SELECT") { if (sqlList.Count > 0 && (i - 1) >= 0 && sqlList[sqlList.Count - 1] != null) { sqlList.Add(null); } } var cmd = new DbRawCommand(sql, context.Parameters, CommandType.Text); sqlList.Add(cmd); if (methodName == "SELECT") { sqlList.Add(cmd); sqlList.Add(null); context = this.CreateTranslateContext(obj is DbRawSql ? ((DbRawSql)obj).DbContext : null); context.Parameters = new List <IDbDataParameter>(8); } else if (cmd.Parameters != null && cmd.Parameters.Count > 1000) { // 1000个参数,就要重新分批 if (haveBegin) { sqlList.Add(new DbRawCommand("END;")); sqlList.Add(null); haveBegin = false; } context = this.CreateTranslateContext(obj is DbRawSql ? ((DbRawSql)obj).DbContext : null); context.Parameters = new List <IDbDataParameter>(8); } } else { if (!haveBegin) { sqlList.Add(new DbRawCommand("BEGIN")); haveBegin = true; } // 解析批量插入操作 List <IDbQueryable> bulkList = obj as List <IDbQueryable>; if (bulkList != null && bulkList.Count > 0) { this.TranslateBulk(sqlList, bulkList); } } if (haveBegin && i == dbQueryables.Count - 1) { sqlList.Add(new DbRawCommand("END;")); } } return(sqlList); }