/// <summary> /// 构造主键的过滤条件。 /// </summary> /// <param name="context">SQL构造上下文信息。</param> /// <param name="sqlInfo">SQL拼装的中间变量。</param> /// <param name="currentObject">主键过滤条件对应的领域对象</param> /// <param name="pkColumnData">主键值Dictionary,Key是ElemetID,Value是列的值。</param> /// <param name="IsUseFieldPrefix">是否使用列全名。</param> /// <returns>主键过滤条件</returns> protected SqlPrimaryKey GetPrimaryKeyConditions(SqlBuildingContext context, SqlBuildingInfo sqlInfo, DomainObject currentObject, IDictionary <string, object> data, bool IsUseFieldPrefix = false) { var curDataObject = currentObject.DataObject; var tableName = context.DataObjectTableMapping[curDataObject.ID]; SqlTable curTable = this.FindSqlTable(tableName, sqlInfo); if (curTable == null) { curTable = new SqlTable(tableName, tableName, tableName); this.RegistSqlTable(tableName, curTable, sqlInfo); } //var data = context.DataContext.GetCurrentDataContextItem(currentObject.ID); var primaryKey = new SqlPrimaryKey(); foreach (var column in curDataObject.PKColumns) { var keyField = new SqlPrimaryKeyField(curTable, column.ColumnName); var pkElement = currentObject.Elements.FirstOrDefault(i => i.DataColumnID == column.ID); keyField.Value.Value = data[pkElement.ID]; keyField.IsUseFieldPrefix = true; primaryKey.ChildCollection.Add(keyField); } return(primaryKey); }
private void ParseDeleteSqlDetail(SqlStatementCollection sqlSchemata, SqlStatementCollection result, DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, DataContext dataContext, Dictionary <string, ShardingTarget> routeInfo) { //构造SQL语句的条件 var strategy = new DeleteSqlBuildStrategy(); var context = new SqlBuildingContext(domainModel, domainObject, domainObject.DataObject.DataSource.DbType, dataContext); context.RouteInfo = routeInfo; var rowSqls = new SqlStatementCollection(); var sqls = sqlSchemata.Where(s => s.SqlBuildingInfo.CurrentNode.ID == domainObject.ID).ToList(); rowSqls.AddRangeClone(sqls); strategy.BuildTableSqlDetail(rowSqls, context); result.AddRange(rowSqls); //递归处理子对象 if (domainObject.ChildDomainObjects.Count == 0) { return; } foreach (var childModelObject in domainObject.ChildDomainObjects) { ParseDeleteSqlDetail(sqlSchemata, result, domainModel, childModelObject, dataContext, routeInfo); } }
/// <summary> /// 根据已经解析的SqlSchema,解析生成带数据的Update语句。 /// </summary> /// <param name="sqlSchemata">已经解析的SqlSchema。</param> /// <param name="domainModel">领域对象</param> /// <param name="context">数据上下文</param> /// <returns>Insert语句集合</returns> private SqlStatementCollection ParseUpdateSqlDetail(SqlStatementCollection sqlSchemata, DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, DataContext dataContext, Dictionary<string, ShardingTarget> routeInfo) { var result = new SqlStatementCollection(); if (!dataContext.Data.ContainsKey(domainObject.ID)) { return result; } var data = dataContext.Data[domainObject.ID]; if (data == null || data.Count == 0) return result; var strategy = new UpdateSqlBuildStrategy(); for (int i = 0; i < dataContext.Data[domainObject.ID].Count; i++) { dataContext.CurrentDataIndex = i; var context = new SqlBuildingContext(domainModel, domainObject, SQLBuilderUtils.GetCurrentDbType(), dataContext); context.RouteInfo = routeInfo; var rowSqls = new SqlStatementCollection(); var sqls = sqlSchemata.Where(s => s.SqlBuildingInfo.CurrentNode.ID == domainObject.ID).ToList(); rowSqls.AddRangeClone(sqls); strategy.BuildTableSqlDetail(rowSqls, context); result.AddRange(rowSqls); } return result; }
/// <summary> /// 获取主键过滤条件。 /// </summary> /// <param name="context">SQL构造上下文信息。</param> /// <param name="domainObject">领域对象</param> /// <param name="curDataObject">数据对象</param> /// <param name="sqlInfo">SQL拼装的中间变量。</param> /// <returns>主键的过滤条件。</returns> private SqlPrimaryKey GetPrimaryKeyCondition(SqlBuildingContext context, DomainObject domainObject, DataObject curDataObject, SqlBuildingInfo sqlInfo) { var tableName = context.DataObjectTableMapping[curDataObject.ID]; SqlTable curTable = this.FindSqlTable(tableName, sqlInfo); if (curTable == null) { curTable = new SqlTable(tableName, tableName, tableName); this.RegistSqlTable(tableName, curTable, sqlInfo); } var data = context.DataContext.GetCurrentDataContextItem(domainObject.ID); if (data.PrimaryKeyData.Count == 0) { return(null); } var primaryKey = new SqlPrimaryKey(); foreach (var column in curDataObject.PKColumns) { var keyField = new SqlPrimaryKeyField(curTable, column.ColumnName); var pkElement = domainObject.Elements.FirstOrDefault(i => i.DataColumnID == column.ID); keyField.Value.Value = data.PrimaryKeyData[pkElement.ID]; keyField.IsUseFieldPrefix = true; primaryKey.ChildCollection.Add(keyField); } return(primaryKey); }
/// <summary> /// 设置UpdateSql的更新数据列。 /// </summary> /// <param name="updateSql">UpdateSql对象。</param> /// <param name="context">Sql构造上下文信息。</param> protected virtual void HandlingUpdateFields(UpdateSqlStatement updateSql, SqlBuildingContext context) { var dataContext = context.DataContext.GetCurrentDataContextItem(context.Node.ID); if (dataContext == null || dataContext.Data == null || dataContext.Data.Count == 0) { updateSql = null; return; } if (updateSql.SqlBuildingInfo.CurrentSqlTable == null) { var tableName = context.TableName; updateSql.SqlBuildingInfo.CurrentSqlTable = base.TryFindAndRegistSqlTable(tableName, tableName, tableName, tableName, updateSql.SqlBuildingInfo); } foreach (string dataItem in dataContext.Data.Keys) { var updateElement = context.Node.Elements.FirstOrDefault(i => i.ID == dataItem); var updateColumn = context.DataObject.Columns.FirstOrDefault(i => i.ID == updateElement.ID); //字段设置 var field = new UpdateField(); field.IsUseFieldPrefix = false; field.IsUseVarBinding = true; field.Table = updateSql.SqlBuildingInfo.CurrentSqlTable; field.FieldName = updateColumn.ColumnName; updateSql.UpdateFields.ChildCollection.Add(field); //字段值设置 var fieldValue = new UpdateValue(); fieldValue.Value = dataContext.Data[dataItem]; updateSql.UpdateValues.ChildCollection.Add(fieldValue); } }
/// <summary> /// 获取CO上某GSPNode的GSPAbsDBTable主键的过滤条件。 /// </summary> /// <param name="context">SQL构造上下文信息。</param> /// <param name="sqlInfo">SQL拼装的中间变量。</param> /// <param name="coNode">主键过滤条件对应的GSPNode。</param> /// <param name="dbTable">主键过滤条件对应的GSPAbsDBTable。</param> /// <param name="IsUseFieldPrefix">是否使用表名</param> /// <returns>主键的过滤条件。</returns> protected string GetPrimaryKeyCondition(SqlBuildingContext context, SqlBuildingInfo sqlInfo, DomainObject coNode, bool IsUseFieldPrefix = false) { var tableName = context.TableName; var tableKey = tableName; var sqlPrimaryKey = new SqlPrimaryKey(); var sqlTable = this.TryFindAndRegistSqlTable(tableKey, tableName, tableName, tableName, sqlInfo); var pkColumnData = context.DataContext.GetCurrentDataContextItem(context.Node.ID).PrimaryKeyData; foreach (DataColumn item in context.DataObject.PKColumns) { var pkElement = context.Node.Elements.FirstOrDefault(i => i.DataColumnID == item.ID); if (pkElement == null) { throw new Exception("Cannot find PkElement, Column ID: " + item.ID); } if (pkColumnData.ContainsKey(pkElement.ID)) { var keyField = new SqlPrimaryKeyField(); keyField.Table = sqlTable; keyField.FieldName = item.ColumnName; keyField.Value.Value = pkColumnData[pkElement.ID]; keyField.IsUseFieldPrefix = IsUseFieldPrefix; sqlPrimaryKey.ChildCollection.Add(keyField); } } return(sqlPrimaryKey.ToSQL()); }
/// <summary> /// 构造不包含数据的Sql(即SqlSchema)。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public override SqlStatementCollection BuildTableSqlSchema(SqlBuildingContext context) { if (context == null) { throw new ArgumentNullException("SelectSqlBuildStrategy.BuildTableSqlSchema"); } var sqls = new SqlStatementCollection(); var selectStatement = SQLStatementFactory.CreateSqlStatement(SqlStatementType.Select, context.DbType) as SelectSqlStatement; selectStatement.SqlBuildingInfo.DataSource = context.DataSource; //Parsing main part of query SQL statement BuildMainFrom(selectStatement, context.CommonObject, context.Node, context.DataObject, context.TableName, context); //Parsing query fields list BuildQueryFieldList(selectStatement, context.Node, context.DataObject); //Parsing inner join clause BuildMainInnerJoin(selectStatement, context); sqls.Add(selectStatement); sqls.ShardingInfo = context.RouteInfo; return(sqls); }
/// <summary> /// 构造Select语句中过滤条件 /// </summary> /// <remarks> /// 根节点和子节点分开处理 /// </remarks> /// <param name="sql">Sql语句对象</param> /// <param name="context">SQL构造上下文</param> public void BuildSQLCondition(SelectSqlStatement sql, SqlBuildingContext context) { //根节点情况 if (sql.SqlBuildingInfo.CurrentNode.ID == sql.SqlBuildingInfo.CommonObject.RootDomainObjectID || sql.SqlBuildingInfo.CurrentNode.IsRootObject) { // 解析授权访问控制的约束条件:主表的查询支持权限关联条件。 this.ParseSecurityCondition(sql, context); // 处理过滤条件中的引用元素 //this.HandlingFilterConditionRefElement(sql, context.FilterCondition, context); // 解析外部传入的过滤条件(表单、帮助、报表等),注:只处理主对象上的过滤条件。 base.GetSelectSqlCondition(sql, context, sql.SqlBuildingInfo.RootNode, sql.SqlBuildingInfo.RootDataObject); //// 解析模型上的过滤条件 //if (filterCondition != null) //{ // sql.FilterCondition.ChildCollection.Add(filterCondition); //} // 解析排序条件 sql.OrderByCondition.ConditionString = base.ParseOrderByCondition(context.OrderByCondition, sql.SqlBuildingInfo); //解析额外的过滤条件 //string extendFilterCondition = ParseExtendFilterCondition(sql.SqlBuildingInfo, context); //if (string.IsNullOrEmpty(extendFilterCondition) == false) //{ // if (string.IsNullOrWhiteSpace(sql.FilterCondition.ConditionString)) // sql.FilterCondition.ConditionString = extendFilterCondition; // else // sql.FilterCondition.ChildCollection.Add = string.Format("{0} and ({1})", sql.FilterCondition.ConditionString, extendFilterCondition); //} // 获取前多少条数据。 sql.TopSize = context.PageSize; } else // 子节点情况 { var mainDo = context.CommonObject.RootDomainObject.DataObject; // 处理过滤条件中的引用元素 //this.HandlingFilterConditionRefElement(sql, context.FilterCondition, context); // 解析外部传入的过滤条件(表单、帮助、报表等),注:只处理主对象上的过滤条件。 //var filterCondition = base.GeInputCondition(context, sql.SqlBuildingInfo.RootNode, // sql.SqlBuildingInfo.RootDataObject, sql.SqlBuildingInfo); //// 解析模型上的过滤条件 //if (filterCondition != null) // sql.FilterCondition.ChildCollection.Add(filterCondition); base.GetSelectSqlCondition(sql, context, sql.SqlBuildingInfo.RootNode, sql.SqlBuildingInfo.RootDataObject); // 解析排序条件 sql.OrderByCondition.ConditionString = base.ParseOrderByCondition(context.OrderByCondition, sql.SqlBuildingInfo); } }
/// <summary> /// 形成包含数据的SQL语句过滤条件。 /// </summary> /// <param name="sql">构造过滤条件的DeleteSql。</param> /// <param name="context">SQL构造的上下文信息。</param> protected void HandlingCondition(DeleteSqlStatement sql, SqlBuildingContext context) { var sqlInfo = sql.SqlBuildingInfo; var currentPrimaryKeyData = context.DataContext.GetCurrentPrimaryKeyData(); //当前是从节点 if (!sqlInfo.CurrentNode.IsRootObject || sqlInfo.CommonObject.RootDomainObjectID != sqlInfo.CurrentNode.ID) { DomainObject currentObject = null; //判断下context.DataContext.PrimaryKeyData数据来自于哪个节点 DataObject currentDataObject = null; foreach (KeyValuePair <string, object> data in currentPrimaryKeyData) { foreach (var modelObject in sqlInfo.CommonObject.DomainObjects) { var element = modelObject.Elements.FirstOrDefault(i => i.ID == data.Key); if (element != null) { currentObject = modelObject; currentDataObject = modelObject.DataObject; break; } } } if (currentObject == null || currentDataObject == null) { var e = new Exception("DomainModel Error PrimaryKeyData! DomainModelID" + sqlInfo.CommonObject.ID); if (currentPrimaryKeyData != null) { foreach (var data in currentPrimaryKeyData) { e.Data.Add(data.Key, data.Value); } } throw e; } //添加根节点的主键值条件 sql.SubQuerySql.Condition.ChildCollection.Add(base.GetPrimaryKeyConditions(context, sql.SqlBuildingInfo, currentObject, currentPrimaryKeyData, true)); } else { // 生成SqlSchema时,形成了子查询。但使用时context.IsUsePrimaryCondition== true,则将子查询置空。 sql.SubQuerySql = null; context.IsUsePrimaryCondition = true; sql.Conditions.ChildCollection.Add(base.GetPrimaryKeyConditions(context, sql.SqlBuildingInfo, sql.SqlBuildingInfo.CurrentNode, currentPrimaryKeyData)); } }
internal ConditionStatement ParseOrderByCondition(SqlBuildingContext context) { if (context.QueryFilter != null) { return(ConditionStatementParser.ParseOrderByClauses(context.QueryFilter.OrderByCondition, context.Node, context.DataObject)); } return(null); }
/// <summary> /// 构造Insert语句中的插入字段 /// </summary> /// <param name="sql">Insert语句</param> /// <param name="context">SQL构造上下文</param> protected void HandlingInsertFields(InsertSqlStatement sql, SqlBuildingContext context) { foreach (var col in context.DataObject.Columns) { sql.InsertFields.ChildCollection.Add(new InsertField() { FieldName = col.ColumnName, IsUseVarBinding = true }); } }
public void BuildSQLJoin(SelectSqlStatement sql, SqlBuildingContext context) { //获取到当前节点的关联关系,排除主从类型的关联 var associations = context.Node.Associations.Where(i => i.AssociateType == AssociateType.OuterLeftJoin); if (associations == null || associations.Count() == 0) return; foreach (var association in associations) { HandlingAssociation(sql, context, association); } }
/// <summary> /// 在SqlSchema基础上,构造包含数据的Sql。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public override void BuildTableSqlDetail(SqlStatementCollection sqls, SqlBuildingContext context) { var sql = sqls.FirstOrDefault(x => x.SqlBuildingInfo.TableName == context.TableName); if (sql == null) return; var querySQL = sql as SelectSqlStatement; //Parsing left join clause of query SQL statement BuildSQLJoin(querySQL, context); //Parsing where clause of query SQL statement BuildSQLCondition(querySQL, context); }
/// <summary> /// 在SqlSchema基础上,构造包含数据的Sql。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public override void BuildTableSqlDetail(SqlStatementCollection sqls, SqlBuildingContext context) { var sql = sqls.FirstOrDefault(i => i.SqlBuildingInfo.CurrentNode.ID == context.Node.ID); if (sql == null) { throw new Exception("DomainObject cannot find SqlSchema, DomainObjectID: " + context.Node.ID); } var deleteStatement = sql as DeleteSqlStatement; this.HandlingCondition(deleteStatement, context); }
/// <summary> /// 处理关联 /// </summary> /// <param name="sql">Select语句</param> /// <param name="context">SQL构造上下文</param> /// <param name="association">关联</param> private void HandlingAssociation(SelectSqlStatement sql, SqlBuildingContext context, Association association) { if (association.AssoDomainObject == null) { throw new Exception("Association cannot find Associate Model: " + association.ID); } if (association.AssoDomainObject == null) { throw new Exception("Association cannot find Associate ModelObject: " + association.ID); } if (association.AssoDomainObject.DataObject == null) { throw new Exception("Association cannot find Associate DataObject: " + association.ID); } //关联中使用的SqlTable,通过关联的ID进行标识,存在一个节点上的多个元素关联同一个表的情况 SqlTable associatedSqlTable = base.FindSqlTable(association.ID, sql.SqlBuildingInfo); if (associatedSqlTable == null) { var assoTableName = context.DataObjectTableMapping[association.AssoDomainObject.DataObject.ID]; associatedSqlTable = base.TryFindAndRegistSqlTable(association.AssoDomainObject.DataObject.ID, assoTableName, assoTableName, assoTableName, sql.SqlBuildingInfo); } var childAssociation = new InternalAssociation() { AssociatedCommonObject = association.AssoDomaiModel, AssociatedCoNode = association.AssoDomainObject, AssociatedDataObject = association.AssoDomainObject.DataObject, AssociatedTable = associatedSqlTable, LocatedCommonObject = sql.SqlBuildingInfo.CommonObject, LocatedDataObject = sql.SqlBuildingInfo.CurrentDataObject, LocatedNode = sql.SqlBuildingInfo.CurrentNode, LocatedTable = sql.SqlBuildingInfo.CurrentSqlTable, Association = association, AdditionalCondition = association.FilterCondition }; foreach (var refElement in association.RefElements) { var element = association.AssoDomainObject.Elements.FirstOrDefault(i => i.ID == refElement.ElementID); var assElement = new InternalRefElement() { Element = element, Label = element.Alias }; childAssociation.RefElements.Add(assElement); } BuildLeftJoin(sql, childAssociation, context); }
/// <summary> /// 在SqlSchema基础上,构造包含数据的Sql。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public override void BuildTableSqlDetail(SqlStatementCollection sqls, SqlBuildingContext context) { var sql = sqls.FirstOrDefault(x => x.SqlBuildingInfo.TableName == context.TableName); if (sql == null) { return; } var updateSql = sql as UpdateSqlStatement; this.HandlingUpdateFields(updateSql, context); this.HandlingConditionInfoAddData(updateSql, context); }
/// <summary> /// 处理带数据的元素 /// </summary> /// <param name="sql">Insert语句</param> /// <param name="context">策略的上下文</param> protected void HandlingFieldsAddData(InsertSqlStatement sql, SqlBuildingContext context) { var excludeField = new List <InsertField>(); foreach (InsertField insertField in sql.InsertFields.ChildCollection) { var insertCol = context.DataObject.Columns.FirstOrDefault(i => i.ColumnName == insertField.FieldName); if (insertCol == null) { throw new Exception("Cannot find column: " + insertField.FieldName); } var insertElement = context.Node.Elements.FirstOrDefault(i => i.DataColumnID == insertCol.ID); if (insertElement == null) { throw new Exception("Cannot find DomainObjectElement, DataColumnID: " + insertCol.ID); } if (!context.DataContext.GetCurrentDataContextItem(context.Node.ID).Data.ContainsKey(insertElement.ID)) { excludeField.Add(insertField); continue; } var fieldValue = new InsertValue(); fieldValue.DataType = Convert.ToInt32(insertElement.DataType); var value = context.DataContext.GetCurrentDataContextItem(context.Node.ID).Data[insertElement.ID]; fieldValue.Value = ElementValueWrapper.ConvertElementValue(insertElement, value); sql.InsertValues.ChildCollection.Add(fieldValue); } if (excludeField != null && excludeField.Count > 0) { foreach (var field in excludeField) { sql.InsertFields.ChildCollection.Remove(field); } } if (sql.InsertFields.ChildCollection.Count == 0) { throw new Exception(string.Format("数据访问服务-插入的字段为空, DomainModel:{0}, DomainObject:{1} ", context.CommonObject.ID, context.Node.ID)); } if (sql.InsertFields.ChildCollection.Count != sql.InsertValues.ChildCollection.Count) { throw new Exception(string.Format("数据访问服务-插入的字段与值个数不匹配, DomainModel:{0}, DomainObject:{1} ", context.CommonObject.ID, context.Node.ID)); } }
/// <summary> /// 在SqlSchema基础上,构造包含数据的Sql。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public override void BuildTableSqlDetail(SqlStatementCollection sqls, SqlBuildingContext context) { var sql = sqls.FirstOrDefault(x => x.SqlBuildingInfo.TableName == context.TableName); if (sql == null) { return; } var insertStatement = sql as InsertSqlStatement; //insertStatement.SqlBuildingInfo = InitSqlBuildingInfo(context.CommonObject, context.Node, context.DataObject, context.TableName); this.HandlingFieldsAddData(insertStatement, context); }
/// <summary> /// 根据SQL构造上下文信息,构造DeleteSql的过滤条件。 /// </summary> /// <param name="context">SQL构造的上下文信息。</param> /// <param name="sql">构造过滤条件的DeleteSql。</param> protected void HandlingJoin(DeleteSqlStatement sql, SqlBuildingContext context) { var currentObject = sql.SqlBuildingInfo.CurrentNode; //1.如果是根节点 if (currentObject.IsRootObject || currentObject.ID == sql.SqlBuildingInfo.CommonObject.RootDomainObjectID || context.IsUsePrimaryCondition) { sql.SubQuerySql = null; return; } //2.如果是从节点或者从从节点 else { var sqlInfo = sql.SqlBuildingInfo; var querySql = new SelectSqlForSubQuery(); //获取当前节点的SQLTable var currentTableName = context.TableName; SqlTable table = base.FindSqlTable(currentTableName, sqlInfo); if (table == null) { table = new SqlTable(currentTableName, currentTableName, currentTableName); base.RegistSqlTable(currentTableName, table, sql.SqlBuildingInfo); } //指定为查询的主表 //querySql.MainFromItem.Table = table; //构造和根节点的关联关系 BuildParentInnerJoin(currentObject, sqlInfo, querySql, context); // 构造删除的主表和子查询的之间的关联关系,支持复合主键 //var rTable = base.FindSqlTable(currentTableName, sql.SqlBuildingInfo); //foreach (var pkColumn in context.DataObject.PKColumns) //{ // querySql.JoinSubQueryConditionItem.LeftField.Table = sql.SqlBuildingInfo.CurrentSqlTable; // querySql.JoinSubQueryConditionItem.RightField.Table = rTable; // querySql.JoinSubQueryConditionItem.LeftField.IsUseFieldPrefix = true; // querySql.JoinSubQueryConditionItem.RightField.IsUseFieldPrefix = true; // querySql.JoinSubQueryConditionItem.LeftField.FieldName = pkColumn.ColumnName; // querySql.JoinSubQueryConditionItem.RightField.FieldName = pkColumn.ColumnName; // //先只循环一次 // break; //} sql.SubQuerySql = querySql; } }
/// <summary> /// 构造查询SQL语句的主干结构 /// </summary> /// <param name="dataObject">数据对象</param> /// <returns>查询SQL语句的主干结构</returns> private void ParseDeleteSqlSchema(SqlStatementCollection sqlSchemata, DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, Dictionary<string, ShardingTarget> routeInfo, DataContext dataContext) { var selectStrategy = new DeleteSqlBuildStrategy(); var context = new SqlBuildingContext(domainModel, domainObject, SQLBuilderUtils.GetCurrentDbType(), dataContext); context.RouteInfo = routeInfo; var nodeSqlSchemata = selectStrategy.BuildTableSqlSchema(context); sqlSchemata.AddRange(nodeSqlSchemata); //递归处理子对象 if (domainObject.ChildDomainObjects.Count == 0) return; foreach (var childModelObject in domainObject.ChildDomainObjects) { ParseDeleteSqlSchema(sqlSchemata, domainModel, childModelObject, routeInfo, dataContext); } }
/// <summary> /// 构造不包含数据的Sql(即SqlSchema)。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public override SqlStatementCollection BuildTableSqlSchema(SqlBuildingContext context) { if (context == null) { throw new ArgumentNullException("UpdateSqlBuildStrategy.BuildTableSqlSchema"); } var sqls = new SqlStatementCollection(); var updateStatement = SQLStatementFactory.CreateSqlStatement(SqlStatementType.Update, context.DbType) as UpdateSqlStatement; updateStatement.SqlBuildingInfo.DataSource = context.DataSource; base.HandlingSqlStatement(updateStatement, context); sqls.Add(updateStatement); return(sqls); }
/// <summary> /// 构造主键的过滤条件。 /// </summary> /// <param name="context">SQL构造上下文信息。</param> /// <param name="sqlInfo">SQL拼装的中间变量。</param> /// <param name="currentObject">主键过滤条件对应的领域对象</param> /// <param name="pkColumnData">主键值Dictionary,Key是ElemetID,Value是列的值。</param> /// <param name="IsUseFieldPrefix">是否使用列全名。</param> /// <returns>主键过滤条件</returns> protected FilterConditionStatement GetPrimaryKeyConditionsEx(SqlBuildingContext context, SqlBuildingInfo sqlInfo, DomainObject currentObject, IDictionary <string, object> pkColumnData, bool IsUseFieldPrefix = false) { var conditionItem = new FilterConditionStatement(); foreach (KeyValuePair <string, object> pkdata in pkColumnData) { var pkElement = currentObject.Elements.FirstOrDefault(i => i.ID == pkdata.Key); var pkColumn = currentObject.DataObject.PKColumns.FirstOrDefault(c => c.ID == pkElement.DataColumnID); var tableName = context.GetTableName(currentObject.DataObject.ID); bool isTextType = DataTypeUtils.IsTextType(pkColumn.DataObjectID); if (isTextType) { var keyCondition = new KeyValueConditionStatement <string>(); keyCondition.Field.FieldName = pkColumn.ColumnName; if (IsUseFieldPrefix) { var sqlTable = this.TryFindAndRegistSqlTable(tableName, tableName, tableName, tableName, sqlInfo); keyCondition.Field.IsUseFieldPrefix = IsUseFieldPrefix; keyCondition.Field.Table = sqlTable; } keyCondition.Value = Convert.ToString(pkdata.Value); keyCondition.LogicalOperator = OperatorType.And; conditionItem.ChildCollection.Add(keyCondition); } else { var keyCondition = new KeyValueConditionStatement <long>(); keyCondition.Field.FieldName = pkColumn.ColumnName; if (IsUseFieldPrefix) { var sqlTable = this.TryFindAndRegistSqlTable(tableName, tableName, tableName, tableName, sqlInfo); keyCondition.Field.IsUseFieldPrefix = IsUseFieldPrefix; keyCondition.Field.Table = sqlTable; } keyCondition.Value = Convert.ToInt64(pkdata.Value); keyCondition.LogicalOperator = OperatorType.And; conditionItem.ChildCollection.Add(keyCondition); } } return(conditionItem); }
/// <summary> /// 构造不包含数据的Sql(即SqlSchema)。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public override SqlStatementCollection BuildTableSqlSchema(SqlBuildingContext context) { if (context == null) { throw new ArgumentNullException("InsertSqlBuilder.BuildTableSqlSchema"); } var sqls = new SqlStatementCollection(); var insertStatement = SQLStatementFactory.CreateSqlStatement(SqlStatementType.Insert, context.DbType) as InsertSqlStatement; base.HandlingSqlStatement(insertStatement, context); HandlingInsertFields(insertStatement, context); insertStatement.SqlBuildingInfo.DataSource = context.DataSource; sqls.Add(insertStatement); return(sqls); }
/// <summary> /// 处理通用中间对象的节点的GSPAbsDBTable。 /// </summary> /// <param name="sql">Sql语句对象。</param> /// <param name="domainModel">领域模型。</param> /// <param name="domainObject">领域对象。</param> /// <param name="dataObject">领域对象对应的数据对象。</param> /// <param name="tableName">表名称。</param> protected void HandlingSqlStatement(SqlStatement sql, SqlBuildingContext context) { sql.NodeID = context.Node.ID; sql.CommonObjectID = context.CommonObject.ID; sql.NodeVersion = context.CommonObject.Version.ToString(); sql.CommonObjectVersion = context.CommonObject.Version.ToString(); sql.TableName = context.TableName; //构造SqlBuildingInfo sql.SqlBuildingInfo = this.InitSqlBuildingInfo(context.CommonObject, context.Node, context.DataObject, context.TableName, context.DataSource); //复合主键 foreach (var item in context.DataObject.PKColumns) { var keyField = new SqlPrimaryKeyField(); keyField.FieldName = item.ColumnName; sql.PrimaryKeys.ChildCollection.Add(keyField); } }
/// <summary> /// 解析外部传入的过滤条件。 /// </summary> /// <param name="context">SQL构造上下文信息。</param> /// <param name="currentObject">主键过滤条件对应的GSPNode。</param> /// <param name="dataObject">主键过滤条件对应的GSPDataTable。</param> /// <param name="sqlInfo">SQL拼装的中间变量。</param> /// <returns>解析后的过滤条件。</returns> protected void GetUpdateSqlCondition(UpdateSqlStatement sql, SqlBuildingContext context, DomainObject currentObject, DataObject dataObject) { //若是非主键形式条件定义。 if (context.IsUseCondition) { var condition = this.GetOrdinaryCondition(context, sql.SqlBuildingInfo); if (condition != null) { sql.UpdateCondition.ChildCollection.Add(condition); } } //若是根据主键值,则获取主键值条件Sql语句。 var sqlPrimaryKey = this.GetPrimaryKeyCondition(context, currentObject, dataObject, sql.SqlBuildingInfo); if (sqlPrimaryKey != null) { sql.UpdateCondition.ChildCollection.Add(sqlPrimaryKey); } }
/// <summary> /// 构造不包含数据的Sql(即SqlSchema)。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public override SqlStatementCollection BuildTableSqlSchema(SqlBuildingContext context) { if (context == null) { throw new ArgumentNullException("DeleteSqlBuildStrategy.BuildTableSqlSchema"); } var sqls = new SqlStatementCollection(); //构造DeleteSql var sql = SQLStatementFactory.CreateSqlStatement(SqlStatementType.Delete, context.DbType) as DeleteSqlStatement; base.HandlingSqlStatement(sql, context); //构造DeleteSql的删除过滤条件 this.HandlingJoin(sql, context); sqls.Add(sql); return(sqls); }
/// <summary> /// 解析生成Insert语句的主干部分。 /// </summary> /// <param name="sqlSchemata">Insert语句的主干。</param> /// <param name="co">通用中间对象。</param> /// <param name="node">通用中间对象的节点。</param> /// <returns>Insert语句的主干部分。</returns> private void ParseInsertSqlSchema(SqlStatementCollection sqlSchemata, DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, Dictionary <string, ShardingTarget> routeInfo) { var insertStrategy = new InsertSqlBuildStrategy(); var context = new SqlBuildingContext(domainModel, domainObject, domainObject.DataObject.DataSource.DbType); context.RouteInfo = routeInfo; var nodeSqlSchemata = insertStrategy.BuildTableSqlSchema(context); sqlSchemata.AddRange(nodeSqlSchemata); //递归处理子对象 if (context.Node.ChildDomainObjects.Count == 0) { return; } foreach (var childModelObject in context.Node.ChildDomainObjects) { ParseInsertSqlSchema(sqlSchemata, domainModel, childModelObject, routeInfo); } }
/// <summary> /// 解析生成Insert语句的主干部分。 /// </summary> /// <param name="sqlSchemata">Insert语句的主干。</param> /// <param name="co">通用中间对象。</param> /// <param name="node">通用中间对象的节点。</param> /// <returns>Insert语句的主干部分。</returns> private void ParseUpdateSqlSchema(SqlStatementCollection sqlSchemata, DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, Dictionary <string, ShardingTarget> routeInfo, DataContext dataContext) { var updateStrategy = new UpdateSqlBuildStrategy(); var context = new SqlBuildingContext(domainModel, domainObject, domainObject.DataObject.DataSource.DbType); context.RouteInfo = routeInfo; if (dataContext.GetCurrentDataContextItem(domainObject.ID) != null) { var nodeSqlSchemata = updateStrategy.BuildTableSqlSchema(context); sqlSchemata.AddRange(nodeSqlSchemata); } //递归处理子对象 if (context.Node.ChildDomainObjects.Count == 0) { return; } foreach (var childModelObject in context.Node.ChildDomainObjects) { ParseUpdateSqlSchema(sqlSchemata, domainModel, childModelObject, routeInfo, dataContext); } }
/// <summary> /// 构造UpdateSql的过滤条件。 /// </summary> /// <param name="sql">Sql语句对象。</param> /// <param name="context">Sql构造上下文信息。</param> private void HandlingConditionInfoAddData(UpdateSqlStatement sql, SqlBuildingContext context) { base.GetUpdateSqlCondition(sql, context, context.Node, context.DataObject); }
/// <summary> /// 构造跟主表的关联。 /// </summary> /// <param name="currentObject">当前的数据模型对象。</param> /// <param name="sqlBuildInfo">SQL构造的中间变量。</param> /// <param name="querySql">删除过滤子查询SQL。</param> /// <remarks> /// 当前对象若是从对象,则需要建立跟主对象的关联, /// 然后根据主对象的唯一标识,形成删除的Sql。 /// </remarks> private void BuildParentInnerJoin(DomainObject currentObject, SqlBuildingInfo sqlBuildInfo, SelectSqlForSubQuery querySql, SqlBuildingContext context) { //如果是根节点,退出 if (currentObject.IsRootObject || currentObject.ID == sqlBuildInfo.CommonObject.RootDomainObjectID) { return; } #region 子节点(当前节点) var currentDataObject = currentObject.DataObject; var tableName = context.GetTableName(currentDataObject.ID); SqlTable currentTable = base.FindSqlTable(tableName, sqlBuildInfo); if (currentTable == null) { currentTable = new SqlTable(tableName, tableName, tableName); base.RegistSqlTable(tableName, currentTable, sqlBuildInfo); } #endregion #region 父节点 var parentObjecct = currentObject.ParentObject; var parentDataObject = parentObjecct.DataObject; var parentTableName = context.GetTableName(parentDataObject.ID); SqlTable parentTable = base.FindSqlTable(parentTableName, sqlBuildInfo); if (parentTable == null) { parentTable = new SqlTable(parentTableName, parentTableName, parentTableName); base.RegistSqlTable(parentTableName, parentTable, sqlBuildInfo); } FromItem parentFromItem = new FromItem(parentTable); querySql.From.ChildCollection.Add(parentFromItem); #endregion #region 关联关系 //目前只是支持单个主对象结构,因此应该只有一个主从关联 var association = currentObject.Associations.FirstOrDefault(i => i.AssociateType == AssociateType.InnerJoin); foreach (var item in association.Items) { //主从关联中,源节点在子节点中,目标节点在父节点上 var sourceElement = currentObject.Elements.FirstOrDefault(i => i.ID == item.SourceElementID); var targetElement = parentObjecct.Elements.FirstOrDefault(i => i.ID == item.TargetElementID); var childCol = currentDataObject.Columns.FirstOrDefault(i => i.ID == sourceElement.ID); var parentCol = parentDataObject.Columns.FirstOrDefault(i => i.ID == targetElement.ID); JoinConditionItem joinItem = new JoinConditionItem(); joinItem.LeftField = new ConditionField(); joinItem.RightField = new ConditionField(); joinItem.LeftField.Table = currentTable; joinItem.LeftField.FieldName = childCol.ColumnName; joinItem.LeftField.IsUseFieldPrefix = true; joinItem.RightField.Table = parentTable; joinItem.RightField.FieldName = parentCol.ColumnName; joinItem.RightField.IsUseFieldPrefix = true; querySql.JoinCondition.ChildCollection.Add(joinItem); } #endregion BuildParentInnerJoin(parentObjecct, sqlBuildInfo, querySql, context); }