/// <summary> /// 执行命令。 /// </summary> /// <param name="command">命令对象。</param> /// <param name="operate">操作对象。</param> /// <returns>影响行数。</returns> public int Execute(DbCommand command, DbOperateBase operate) { if (Parameters.Count > 0) { command.Parameters.AddRange(Parameters.ToArray()); } LoadParameter(command, operate); var isoutput = operate.HasResult && operate.Output != null; if (isoutput) { if (ReturnParameters.Count > 0) { var parameters = ReturnParameters.Select(a => a.Parameter).ToArray(); var result = command.ExecuteNonQuery(); var objectOperates = (DbObjectsOperateBase)operate; objectOperates.Read(parameters); return(result); } else { using (var reader = command.ExecuteReader()) { operate.Read(reader); return(reader.RecordsAffected); } } } else { return(command.ExecuteNonQuery()); } }
/// <summary> /// 创建数据操作内容。 /// </summary> /// <param name="context">生成上下文。</param> /// <param name="operate">操作对象。</param> internal OperateContentBase(GenerateContext context, DbOperateBase operate) { GenerateContext = context; var operateContext = operate.Executor; Operate = operate; OperateCommand = operateContext.CurrentCommand; DataContext = operateContext.Context; }
public static void CompareSql(DbContext db, DbOperateBase ope, string sql) { DbOperateBase operate = (DbOperateBase)ope; var comands = new DbOperateCommandCollection(operate.Executor); comands.NextCommand(); var generatesql = ope.GenerateSql(); CompareSql(sql, generatesql); }
/// <summary> /// 根据指定操作及表达式生成语句。 /// </summary> /// <param name="operate">操作对象。</param> /// <param name="content">表达式。</param> /// <returns>生成的语句。</returns> public string Generate(DbOperateBase operate, DbExpression content) { var context = new GenerateContext(operate, this); context.Data.Inititalze(content); if (!_GenerateFragmentMethods.TryGetValue(context.Data.GetType(), out GenerateFragmentDelegate method)) { throw new NotImplementedException(); } var fragment = method(context, content); return(fragment.ToString()); }
/// <summary> /// 创建语句生成上下文。 /// </summary> /// <param name="operate">操作对象。</param> /// <param name="generator">值生成对象。</param> public GenerateContext(DbOperateBase operate, SqlGeneratorBase generator) { var operateContext = operate.Executor; var dataContext = operateContext.Context; Generator = generator; _FragmentWriter = generator.FragmentWriter; var configure = dataContext.Configuration; Metadata = configure.Metadata; _Translator = configure.Translator; Feature = dataContext.Database.Feature; Data = generator.CreateData(this, operate); }
/// <summary> /// 执行命令。 /// </summary> /// <param name="command">指定的命令对象。</param> /// <param name="operate">当前操作对象。</param> /// <returns>执行后的影响行数。</returns> public int Execute(DbCommand command, DbOperateBase operate) { if (_Parameters.Count > 0) { command.Parameters.AddRange(_Parameters.ToArray()); } var strs = command.CommandText.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); if (!(operate is IDbSplitObjectsOperate objects)) { throw new InvalidOperationException(); } var recordsAffectedCount = 0; var bodys = _ParameterBody.Values; if (operate.HasResult && operate.Output != null) { var objectsOperate = (DbObjectsOperateBase)operate; foreach (var obj in objects) { _Loader.Load(obj); foreach (var body in bodys) { body.Parameter.Value = _Loader[body.Index]; } var returnCommand = RunSpliteCommand(command, strs, out int affectedCount); using (var reader = returnCommand.ExecuteReader()) { objectsOperate.Read(reader, obj); recordsAffectedCount += affectedCount + reader.RecordsAffected; } } } else { foreach (var obj in objects) { _Loader.Load(obj); foreach (var body in bodys) { body.Parameter.Value = _Loader[body.Index]; } var returnCommand = RunSpliteCommand(command, strs, out int affectedCount); recordsAffectedCount += affectedCount + returnCommand.ExecuteNonQuery(); } } return(recordsAffectedCount); }
/// <summary> /// 向命令集合注册数据库操作。 /// </summary> /// <param name="operate">注册的操作。</param> /// <param name="parametercount">最大参数数量。</param> public void Register(DbOperateBase operate, int parametercount) { var command = this.CheckParameterCount(parametercount); if (command.ConcurrencyExpectCount > 0 || command is SingleOperateCommand) { //如果当前命令包含并发检查操作,则移动到下一个命令中。 command = this.NextCommand(); } command.RegisteOperate(operate); if (operate is IConcurrencyCheckOperate concurrency2 && concurrency2.NeedCheck) { command.ConcurrencyExpectCount += concurrency2.ExpectCount; } }
/// <summary> /// 创建语句生成上下文。 /// </summary> /// <param name="operate">操作对象。</param> /// <param name="generator">值生成对象。</param> public GenerateContext(DbOperateBase operate, SqlGeneratorBase generator) { var operateContext = operate.Executor; var dataContext = operateContext.Context; Generator = generator; _FragmentWriter = generator.FragmentWriter; var configure = dataContext.Configuration; Metadata = configure.Metadata; _Translator = configure.Translator; Feature = dataContext.Database.Feature; switch (operate.Type) { case EOperateType.InsertObjects: case EOperateType.InsertPropertys: Data = new GenerateDataForInsert(this, operate as DbObjectsOperateBase); break; case EOperateType.UpdateObjects: case EOperateType.UpdatePropertys: Data = new GenerateDataForUpdate(this, operate as DbObjectsOperateBase); break; case EOperateType.DeleteObjects: Data = new GenerateDataForDelete(this, operate as DbObjectsOperateBase); break; case EOperateType.AddRelation: case EOperateType.RemoveRelation: Data = new GenerateDataForRelation(this, operate as DbRelationOperateBase); break; case EOperateType.InsertStatement: case EOperateType.UpdateStatement: case EOperateType.DeleteStatement: Data = new GenerateDataForStatement(this, operate as DbStatementOperateBase); break; default: Data = new GenerateData(this, operate); break; } }
/// <summary> /// 根据指定操作及表达式生成语句。 /// </summary> /// <param name="operate">操作对象。</param> /// <param name="content">表达式。</param> /// <returns>生成的语句。</returns> public string Generate(DbOperateBase operate, DbExpression content) { var context = new GenerateContext(operate, this); context.Data.Inititalze(content); SqlFragment fragment = null; switch (operate.Type) { case EOperateType.InsertObjects: fragment = GenerateForInsert(context); break; case EOperateType.UpdateObjects: fragment = GenerateForUpdate(context); break; case EOperateType.DeleteObjects: fragment = GenerateForDelete(context); break; case EOperateType.QueryObject: case EOperateType.QueryCollection: fragment = GenerateForQuery(context, content); break; case EOperateType.InsertPropertys: fragment = GenerateForInsert(context, content); break; case EOperateType.UpdatePropertys: fragment = GenerateForUpdate(context, content); break; case EOperateType.InsertStatement: fragment = GenerateForInsertStatement(context, content); break; case EOperateType.UpdateStatement: fragment = GenerateForUpdateStatement(context, content); break; case EOperateType.DeleteStatement: fragment = GenerateForDeleteStatement(context, content); break; case EOperateType.AddRelation: case EOperateType.RemoveRelation: fragment = GenerateForRelation(context); break; default: if (operate is DbMaintenanceOperateBase maintenance) { fragment = GenerateForMaintenance(context); } break; } return(fragment.ToString()); }
/// <summary> /// 翻译指定的操作。 /// </summary> /// <param name="operate">目标操作。</param> /// <returns>数据表达式。</returns> public DbExpression Translate(DbOperateBase operate) { Utility.NotNull(operate, nameof(operate)); var context = operate.Executor.Context; switch (operate) { case DbQueryOperateBase query: return(Translate(query.Expression, context)); case DbPropertysOperateBase propertys: return(Translate(propertys.Expression, context)); case DbObjectsOperateBase objects: return(Translate(objects.Expression, context)); case DbRelationOperateBase relations: return(new DbDataSetExpression(typeof(IEnumerable <>).MakeGenericType(relations.ClrType))); case DbStatementOperateBase statement: return(Translate(statement.Expression, context)); } throw new ArgumentException(string.Format(Res.NotSupportedParseOperate, operate.Type)); }
/// <summary> /// 注册操作。 /// </summary> /// <param name="operate">操作对象。</param> internal abstract void RegisteOperate(DbOperateBase operate);
/// <inheritdoc/> internal override void RegisteOperate(DbOperateBase operate) { Operate = operate; _Statement = operate.GenerateSql(); }
//向参数以数组的形式加载所有数据对象 private void LoadParameter(DbCommand command, DbOperateBase operate) { if (MemberParameters.Count > 0) { var items = (IDbSplitObjectsOperate)operate; if (items.Count == 1) { foreach (var item in items) { LoadParameter(item); } foreach (var parameter in ReturnParameters) { parameter.Parameter.Value = GetDefaultValue(parameter.Metadata.StorageType); var storageType = parameter.Metadata.StorageType; if (!storageType.IsValueType) { parameter.Parameter.Size = 4000; } } } else { var index = 0; var arrayList = MemberParameters.ToDictionary(a => a.Parameter, a => { var values = Array.CreateInstance(a.Metadata.StorageType, items.Count); a.Parameter.Value = values; return(values); }); var loader = Loader; foreach (var item in items) { loader.Load(item); foreach (var p in MemberParameters) { arrayList[p.Parameter].SetValue(Loader[p.Index], index); } index++; } OracleAccessProvider.SetArrayBindCount(command, items.Count); int[] shortArray = null, longArray = null; foreach (var member in ReturnParameters) { var storageType = member.Metadata.StorageType; member.Parameter.Value = Array.CreateInstance(storageType, items.Count); if (storageType.IsValueType) { shortArray = shortArray ?? Utility.Array(items.Count, 38); OracleAccessProvider.SetArrayBindSize(member.Parameter, shortArray); } else { longArray = longArray ?? Utility.Array(items.Count, 4000); OracleAccessProvider.SetArrayBindSize(member.Parameter, longArray); } } foreach (var para in SimpleParameters) { var value = para.Value; var values = Array.CreateInstance(value.GetType(), items.Count); for (int i = 0; i < values.Length; i++) { values.SetValue(value, i); } para.Value = values; } } } }