/// <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); }
/// <summary> /// 构造函数 /// </summary> /// <param name="table">表</param> /// <param name="fieldName">字段</param> public ConditionField(SqlTable table, string fieldName) : base(table, fieldName) { }
/// <summary> /// 构造查询SQL语句中表主要的内连接部分 /// </summary> /// <remarks> /// 处理时分为几种场景: /// 1. 当前节点是根节点时,不做任何处理 /// 2. 当前节点不是根节点时,此时需要和父节点进行内连接关联过滤数据(例如主从结构), /// 如果关联的父节点不是根节点,上级也存在父节点(例如主从从结构),此时要进行递归循环处理 /// 提示: /// 所有内连接的场景均是在同一个领域模型情形下,不可能关联到其他CO的节点。 /// </remarks> /// <param name="sql">Sql语句对象</param> /// <param name="domainModel">通用中间对象</param> /// <param name="currentObject">当前解析用到的节点对象</param> /// <param name="dataObject">当前解析用到的节点对象对应的数据对象</param> public void BuildMainInnerJoin(SelectSqlStatement sql, SqlBuildingContext context) { var currentObject = context.Node; var dataObject = context.DataObject; //当前节点是根节点时, 直接返回 if (currentObject.IsRootObject || context.CommonObject.RootDomainObject.ID == currentObject.ID) return; //获取到当前节点的主从关联,主从关系中的主从关联关系是存放在子节点的关联集合上 var associations = currentObject.Associations.Where(i => i.AssociateType == AssociateType.InnerJoin); if (associations == null || associations.Count() == 0) return; var currentTableName = context.DataObjectTableMapping[dataObject.ID]; SqlTable cTable = base.FindSqlTable(currentTableName, sql.SqlBuildingInfo); if (cTable == null) { cTable = base.TryFindAndRegistSqlTable(currentTableName, currentTableName, currentTableName, currentTableName, sql.SqlBuildingInfo); } string parentDataObjectID = currentObject.ParentObject.DataObjectID; var parentTableName = context.DataObjectTableMapping[parentDataObjectID]; SqlTable pTable = base.FindSqlTable(parentTableName, sql.SqlBuildingInfo); if (pTable == null) { pTable = base.TryFindAndRegistSqlTable(parentTableName, parentTableName, parentTableName, parentTableName, sql.SqlBuildingInfo); } var innerJoin = new InnerJoinItem(); innerJoin.InnerJoinTable = pTable; foreach (Association association in associations) { foreach (var item in association.Items) { var srcElement = currentObject.Elements.FirstOrDefault(i => i.ID == item.SourceElementID); var srcColumn = dataObject.Columns.FirstOrDefault(i => i.ID == srcElement.DataColumnID); if (srcColumn == null) throw new Exception("Cannot find inner join column:" + srcElement.DataColumnID); var targetElement = currentObject.ParentObject.Elements.FirstOrDefault(i => i.ID == item.TargetElementID); var targetColumn = currentObject.ParentObject.DataObject.Columns.FirstOrDefault(i => i.ID == targetElement.DataColumnID); if (srcColumn == null) throw new Exception("Cannot find inner join column:" + targetElement.DataColumnID); var joinItem = new JoinConditionItem(); joinItem.LeftField = new ConditionField(); joinItem.RightField = new ConditionField(); joinItem.LeftField.Table = cTable; joinItem.LeftField.IsUseFieldPrefix = true; joinItem.LeftField.FieldName = srcColumn.ColumnName; joinItem.RightField.Table = pTable; joinItem.RightField.IsUseFieldPrefix = true; joinItem.RightField.FieldName = targetColumn.ColumnName; innerJoin.ChildCollection.Add(joinItem); } sql.MainFromItem.ChildCollection.Add(innerJoin); //如果关联的父节点上还有存在父级节点,递归进行处理,直至根节点退出 if (association.AssoDomainObject.ParentObject != null) { context.Node = association.AssoDomainObject.ParentObject; context.DataObject = association.AssoDomainObject.ParentObject.DataObject; BuildMainInnerJoin(sql, context); } } }
/// <summary> /// 构造函数 /// </summary> /// <param name="table">表</param> public FromItem(SqlTable table) : this() { Table = table; }
/// <summary> /// 构造函数 /// </summary> /// <param name="table">隶属的表</param> /// <param name="fieldName">字段名称</param> public Field(SqlTable table, string fieldName) : base() { Table = table; FieldName = fieldName; }
/// <summary> /// 构造函数 /// </summary> public Field() : base() { Table = new SqlTable(); }
/// <summary> /// 构造函数 /// </summary> public LeftJoinItem() : base() { LeftJoinTable = new SqlTable(); base.CreateChildCollection(); }