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> /// 构造函数(Default\Insert\Delete场景) /// </summary> /// <param name="domainModel">领域模型</param> /// <param name="domainObject">领域对象</param> /// <param name="dbType">数据库类型</param> public SqlBuildingContext(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, DbType dbType) { this.DbType = dbType; this.Node = domainObject; this.DataObject = domainObject.DataObject; this.CommonObject = domainModel; }
/// <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, DomainModel.Spi.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); }
/// <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, DomainModel.Spi.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> /// 批量删除 /// </summary> /// <remarks>按主键数据作为查询依据</remarks> /// <param name="domainModel">领域模型</param> /// <param name="domainObject">领域对象</param> /// <param name="dataID">主键数据</param> /// <param name="shardingKeyValue">分库分表键值对</param> /// <returns>删除SQL</returns> public void DeleteByIDs(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, IEnumerable <string> dataIDs, ShardingValue shardingKeyValue = null) { if (domainModel == null) { throw new ArgumentNullException("DataDeleteService.DeleteByID.domainModel"); } if (domainObject == null) { throw new ArgumentNullException("DataDeleteService.DeleteByID.domainObject"); } if (dataIDs == null || dataIDs.Count() == 0) { throw new ArgumentNullException("DataDeleteService.DeleteByID.dataIDs"); } var sqlList = new SqlStatementCollection(); foreach (var dataID in dataIDs) { var sqls = SQLBuilderFactory.CreateSQLBuilder().ParseDeleteSqlByID(domainModel, domainObject, dataID, shardingKeyValue); sqlList.AddRange(sqls); } var db = DatabaseFactory.CreateDefaultDatabase(); db.ExecuteSQLWithTransaction(sqlList); }
private static void LoopGetModelObjectPropValue(DomainModel.Spi.DomainObject domainObject, DataContext context, object data, DataAccessOpType opType, bool isUseDbNull) { if (domainObject.ChildDomainObjects.Count > 0) { foreach (var childModelObject in domainObject.ChildDomainObjects) { var objectList = ObjectPropertyValueUtils.GetCollectionPropValue(childModelObject.PropertyName, data); var items = new List <DataContextItem>(objectList.Count()); foreach (var obj in objectList) { items.Add(GetModelObjectPropValue(obj, childModelObject, opType, isUseDbNull)); } context.Add(childModelObject.ID, items); } } }
/// <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, DomainModel.Spi.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.RelationOperator = 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.RelationOperator = OperatorType.And; conditionItem.ChildCollection.Add(keyCondition); } } return(conditionItem); }
/// <summary> /// 更新领域模型数据 /// </summary> /// <param name="domainModel">领域模型</param> /// <param name="domainObject">领域对象</param> /// <param name="instance">对象实例</param> /// <param name="shardingValue">分区分表键值对</param> public void Update(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, object instance, ShardingValue shardingValue = null) { if (domainModel == null) { throw new ArgumentNullException("DataUpdateService.Update.domainModel"); } if (domainObject == null) { throw new ArgumentNullException("DataUpdateService.Update.domainObject"); } if (instance == null) { throw new ArgumentNullException("DataUpdateService.Update.instance"); } var sqls = SQLBuilderFactory.CreateSQLBuilder().ParseUpdateSql(domainModel, domainObject, instance, shardingValue); var db = DatabaseFactory.CreateDefaultDatabase(); db.ExecuteSQLWithTransaction(sqls); }
/// <summary> /// 删除 /// </summary> /// <remarks>按主键数据作为查询依据</remarks> /// <param name="domainModel">领域模型</param> /// <param name="domainObject">领域对象</param> /// <param name="dataID">主键数据</param> /// <param name="shardingKeyValue">分库分表键值对</param> /// <returns>删除SQL</returns> public void DeleteByID(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, string dataID, ShardingValue shardingKeyValue = null) { if (domainModel == null) { throw new ArgumentNullException("DataDeleteService.DeleteByID.domainModel"); } if (domainObject == null) { throw new ArgumentNullException("DataDeleteService.DeleteByID.domainObject"); } if (string.IsNullOrWhiteSpace(dataID)) { throw new ArgumentNullException("DataDeleteService.DeleteByID.dataID"); } var sqls = SQLBuilderFactory.CreateSQLBuilder().ParseDeleteSqlByID(domainModel, domainObject, dataID, shardingKeyValue); var db = DatabaseFactory.CreateDefaultDatabase(); db.ExecuteSQLWithTransaction(sqls); }
/// <summary> /// 保存领域模型数据 /// </summary> /// <param name="domainModel">领域模型</param> /// <param name="domainObject">领域对象</param> /// <param name="instance">对象实例</param> /// <param name="shardingValueList">分区分表键值对集合</param> public void SaveBatch(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, IList <object> instanceList, List <ShardingValue> shardingValueList = null) { if (domainModel == null) { throw new ArgumentNullException("SaveService.Save.domainModel"); } if (domainObject == null) { throw new ArgumentNullException("SaveService.Save.domainObject"); } if (instanceList == null) { throw new ArgumentNullException("SaveService.Save.instanceList"); } var sqls = new SqlStatementCollection(); for (int i = 0; i < instanceList.Count; i++) { var currentObj = instanceList[i]; ShardingValue shardingValue = null; if (shardingValueList != null) { shardingValue = shardingValueList[i]; } var sqlstatements = SQLBuilderFactory.CreateSQLBuilder().ParseInsertSql(domainModel, domainObject, currentObj, shardingValue); sqls.AddRange(sqlstatements); } var db = DatabaseFactory.CreateDefaultDatabase(); db.ExecuteSQLWithTransaction(sqls); }
/// <summary> /// 解析生成查询SQL /// </summary> /// <remarks>按主键数据作为查询依据</remarks> /// <param name="domainModel">领域模型</param> /// <param name="domainObject">领域对象</param> /// <param name="filter">过滤器</param> /// <returns>查询SQL</returns> public SqlStatementCollection ParseQuerySqlByFilter(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, QueryFilter filter) { var sqls = new SqlStatementCollection(); return sqls; }
/// <summary> /// 解析生成查询SQL /// </summary> /// <remarks>按主键数据作为查询依据</remarks> /// <param name="domainModel">领域模型</param> /// <param name="domainObject">领域对象</param> /// <param name="dataID">主键数据</param> /// <param name="shardingKeyValue">分库分表键值对</param> /// <returns>查询SQL</returns> public SqlStatementCollection ParseQuerySqlByID(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, string dataID, ShardingValue shardingKeyValue = null) { var sqls = new SqlStatementCollection(); var sqlSchema = new SqlStatementCollection(); var routeInfo = routeService.RouteByDataID(domainModel, dataID, shardingKeyValue); var dataIDDic = CreatePkDataDictionary(domainModel, domainObject, dataID); var dataContext = DataContextBuilder.CreateDataContext<IDictionary<string, object>>(domainModel, domainObject, DataAccessOpType.Q, dataIDDic); //解析SQL语句主干接口 ParseQuerySqlSchema(sqlSchema, domainModel, domainObject, routeInfo, dataContext); //在SqlSchema上逐表添加数据 ParseQuerySqlDetail(sqlSchema, sqls, domainModel, domainObject, dataContext, routeInfo); return sqlSchema; }
private Dictionary<string, object> CreatePkDataDictionary(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, string dataID) { var dataIDDic = new Dictionary<string, object>(); foreach (var column in domainObject.DataObject.PKColumns) { var pkElement = domainObject.Elements.FirstOrDefault(i => i.DataColumnID == column.ID); dataIDDic.Add(pkElement.ID, dataID); break; } return dataIDDic; }
/// <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> /// 解析生成Update语句。 /// </summary> /// <param name="domainModel">领域模型。</param> /// <param name="instance">要更新的数据。</param> /// <param name="shardingKeyValue">分库分表键值对</param> /// <returns>Update语句集合。</returns> public SqlStatementCollection ParseUpdateSql(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject momainObject, object instance, ShardingValue shardingKeyValue = null) { var sqls = new SqlStatementCollection(); var routeInfo = routeService.Route(domainModel, instance, shardingKeyValue); var dataContext = DataContextBuilder.CreateDataContext<object>(domainModel, momainObject, DataAccessOpType.U, instance); //解析SQL语句主干接口 ParseUpdateSqlSchema(sqls, domainModel, momainObject, routeInfo, dataContext); //在SqlSchema上逐表添加数据 return ParseUpdateSqlDetail(sqls, domainModel, dataContext, routeInfo); }
protected static DataContext CreateUpdateContext(DomainModel.Spi.DomainModel model, DomainModel.Spi.DomainObject domainObject, object data) { var context = new DataContext(); var dataContextItem = GetModelObjectPropValue(data, domainObject, DataAccessOpType.U, true); context.Add(domainObject.ID, new List <DataContextItem>() { dataContextItem }); if (domainObject.ChildDomainObjects.Count > 0) { foreach (var childModelObject in domainObject.ChildDomainObjects) { var objectList = ObjectPropertyValueUtils.GetCollectionPropValue(childModelObject.PropertyName, data); var items = new List <DataContextItem>(objectList.Count()); foreach (var obj in objectList) { items.Add(GetModelObjectPropValue(obj, childModelObject, DataAccessOpType.U, true)); LoopGetModelObjectPropValue(childModelObject, context, obj, DataAccessOpType.U, true); } context.Add(childModelObject.ID, items); } } return(context); }
public static List <T> MapToObjects <T>(QueryResultSet resultSet, DomainModel.Spi.DomainModel model, DomainModel.Spi.DomainObject domainObject = null) where T : class { if (resultSet == null) { throw new ArgumentNullException("ORMappingService.MapToObject.resultSet"); } if (model == null) { throw new ArgumentNullException("ORMappingService.MapToObject.model"); } if (domainObject == null) { domainObject = model.RootDomainObject; } var plugin = ORMPluginFactory.GetInstance().GetOrCreatePlugin(model); var objs = plugin.MapToObjects(resultSet, model, domainObject); return(new List <T>(objs.Select(i => i as T))); }
private static DataContextItem GetModelObjectPropValue(object data, DomainModel.Spi.DomainObject domainObject, DataAccessOpType opType, bool isUseDbNull) { var dataContextItem = new DataContextItem() { OpType = opType }; foreach (var element in domainObject.Elements) { if (string.IsNullOrWhiteSpace(element.PropertyName)) { continue; } bool isPkElement = domainObject.DataObject.Columns.FirstOrDefault(i => i.ID == element.DataColumnID).IsPkColumn; var propValue = ObjectPropertyValueUtils.GetPropValue(element.PropertyName, data); if (propValue != null) { dataContextItem.Data.Add(element.ID, propValue); if (isPkElement) { dataContextItem.PrimaryKeyData.Add(element.ID, propValue); } } else if (isUseDbNull) { dataContextItem.Data.Add(element.ID, DBNull.Value); if (isPkElement) { dataContextItem.PrimaryKeyData.Add(element.ID, DBNull.Value); } } } foreach (var association in domainObject.Associations) { if (association.AssociateType == AssociateType.InnerJoin) { continue; } var associationObject = ObjectPropertyValueUtils.GetPropValue(association.PropertyName, data); foreach (var assoItem in association.Items) { var element = association.AssoDomainObject.Elements.FirstOrDefault(i => i.ID == assoItem.TargetElementID); if (element == null) { throw new Exception("Invalid Association:" + assoItem.TargetElementID); } var propValue = ObjectPropertyValueUtils.GetPropValue(element.PropertyName, associationObject); if (propValue != null) { dataContextItem.Data.Add(assoItem.SourceElementID, propValue); } else if (isUseDbNull) { dataContextItem.Data.Add(assoItem.SourceElementID, DBNull.Value); } } } return(dataContextItem); }
/// <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, domainObject.DataObject.DataSource.DbType, 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构造中间变量 /// </summary> /// <param name="commonObject">通用中间对象</param> /// <param name="coNode">节点</param> /// <param name="dataObject">数据对象</param> /// <param name="currentDbTable">当前操作对应的数据库表</param> /// <returns>SQL构造中间变量</returns> protected SqlBuildingInfo InitSqlBuildingInfo(DomainModel.Spi.DomainModel commonObject, DomainModel.Spi.DomainObject coNode, DataObject dataObject, string tableName, string dataSourceName) { //构造SqlBuildingInfo var sqlInfo = new SqlBuildingInfo(); sqlInfo.CommonObject = commonObject; sqlInfo.RootNode = commonObject.RootDomainObject; sqlInfo.CurrentNode = coNode; sqlInfo.CurrentDataObject = dataObject; sqlInfo.TableName = tableName; sqlInfo.DataSource = dataSourceName; sqlInfo.CurrentSqlTable = new SqlTable(sqlInfo.TableName, sqlInfo.TableName, sqlInfo.TableName); //SqlTable注册处理 RegistSqlTable(sqlInfo.CurrentSqlTable.TableName, sqlInfo.CurrentSqlTable, sqlInfo); //如果当前节点是根节点: if (sqlInfo.RootNode.ID == sqlInfo.CurrentNode.ID) { sqlInfo.RootDataObject = dataObject; sqlInfo.RootSqlTable = sqlInfo.CurrentSqlTable; } else { sqlInfo.RootDataObject = commonObject.RootDomainObject.DataObject; //sqlInfo.RootSqlTable = GetSubQuerySql(commonObject, commonObject.RootNode); } //SqlTable再次注册处理 RegistSqlTable(sqlInfo.CurrentSqlTable.TableName, sqlInfo.CurrentSqlTable, sqlInfo); return(sqlInfo); }
/// <summary> /// 构造数据上下文 /// </summary> /// <typeparam name="T">数据类型</typeparam> /// <param name="model">领域模型</param> /// <param name="opType">数据访问类型</param> /// <param name="data">数据</param> /// <returns>数据上下文</returns> public static DataContext CreateDataContext <T>(DomainModel.Spi.DomainModel model, DomainModel.Spi.DomainObject domainObject, DataAccessOpType opType, T data) { DataContext dataContext = null; switch (opType) { case DataAccessOpType.I: dataContext = CreateSaveContext(model, domainObject, data); break; case DataAccessOpType.Q: dataContext = CreateQueryContext(model, domainObject, data as IDictionary <string, object>); break; case DataAccessOpType.U: dataContext = CreateUpdateContext(model, domainObject, data); break; case DataAccessOpType.D: dataContext = CreateDeleteContext(model, domainObject, data as IDictionary <string, object>); break; default: break; } return(dataContext); }
protected static DataContext CreateDeleteContext(DomainModel.Spi.DomainModel model, DomainModel.Spi.DomainObject domainObject, IDictionary <string, object> pkData) { var context = new DataContext(); var dataContextItem = new DataContextItem() { OpType = DataAccessOpType.D }; dataContextItem.PrimaryKeyData = pkData; context.Add(domainObject.ID, new List <DataContextItem>() { dataContextItem }); return(context); }
/// <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, DomainModel.Spi.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 /// </summary> /// <remarks>按主键数据作为查询依据</remarks> /// <param name="domainModel">领域模型</param> /// <param name="domainObject">领域对象</param> /// <param name="dataID">主键数据</param> /// <param name="shardingKeyValue">分库分表键值对</param> /// <returns>删除SQL</returns> public SqlStatementCollection ParseDeleteSqlByID(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, string dataID, ShardingValue shardingKeyValue = null) { var sqls = new SqlStatementCollection(); var sqlSchema = new SqlStatementCollection(); var routeInfo = routeService.RouteByDataID(domainModel, dataID, shardingKeyValue); var dataIDDic = CreatePkDataDictionary(domainModel, domainModel.RootDomainObject, dataID); var dataContext = DataContextBuilder.CreateDataContext<IDictionary<string, object>>(domainModel, domainObject, DataAccessOpType.D, dataIDDic); //解析SQL语句主干接口 ParseDeleteSqlSchema(sqlSchema, domainModel, domainObject, routeInfo, dataContext); //在SqlSchema上逐表添加数据 ParseDeleteSqlDetail(sqlSchema, sqls, domainModel, domainObject, dataContext, routeInfo); var result = new SqlStatementCollection(); foreach (var tempDomainObject in domainModel.ReverseDomainObjects) { var sql = sqls.FirstOrDefault(i => i.NodeID == tempDomainObject.ID); if (sql != null) { result.Add(sql); } } return result; }
/// <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, SQLBuilderUtils.GetCurrentDbType()); 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> /// Sharding路由 /// </summary> /// <param name="domainModel">领域模型</param> /// <param name="instance">数据</param> /// <param name="shardingKeyValue">ShardingValue</param> /// <returns>路由</returns> public Dictionary <string, ShardingTarget> Route(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, object instance, ShardingValue shardingKeyValue = null) { var targets = new Dictionary <string, ShardingTarget>(); if (shardingKeyValue == null) { shardingKeyValue = CreateShardingValue(domainModel, domainObject, instance); } if (shardingKeyValue.ShardingValueType != ShardingValueType.SINGLE) { throw new Exception("Object Sharding route error: " + shardingKeyValue.ShardingValueType); } var tars = ShardingRuleService.GetInstance().Parse(domainObject.DataObject, shardingKeyValue); targets.Add(domainObject.DataObject.ID, tars[0]); return(targets); }
/// <summary> /// 构造函数(Default\Insert\Delete场景) /// </summary> /// <param name="domainModel">通用中领域模型间对象</param> /// <param name="domainObject">领域对象</param> /// <param name="dbType">数据库类型</param> /// <param name="dataContext">数据上下文</param> public SqlBuildingContext(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, DbType dbType, DataContext dataContext) : this(domainModel, domainObject, dbType) { this.DataContext = dataContext; }
/// <summary> /// 初始化SQL构造中间变量 /// </summary> /// <param name="commonObject">通用中间对象</param> /// <param name="coNode">节点</param> /// <param name="dataObject">数据对象</param> /// <param name="currentDbTable">当前操作对应的数据库表</param> /// <returns>SQL构造中间变量</returns> protected SqlBuildingInfo InitSqlBuildingInfoForSelect(DomainModel.Spi.DomainModel commonObject, DomainModel.Spi.DomainObject coNode, DataObject dataObject, string tableName) { var sqlInfo = new SqlBuildingInfo() { CommonObject = commonObject, RootNode = commonObject.RootDomainObject, CurrentNode = coNode, CurrentDataObject = dataObject, TableName = tableName }; sqlInfo.CurrentSqlTable = new SqlTable(sqlInfo.TableName, sqlInfo.TableName, sqlInfo.TableName); //如果当前节点是根节点: if (sqlInfo.CurrentNode.IsRootObject || sqlInfo.RootNode.ID == sqlInfo.CurrentNode.ID) { sqlInfo.RootDataObject = dataObject; sqlInfo.RootSqlTable = sqlInfo.CurrentSqlTable; } else { sqlInfo.RootDataObject = commonObject.RootDomainObject.DataObject; //sqlInfo.RootSqlTable = CoHelper.GetRootSQLDomTable(commonObject); } RegistSqlTable(sqlInfo.CurrentDataObject.ID, sqlInfo.CurrentSqlTable, sqlInfo); return(sqlInfo); }
/// <summary> /// 构造ShardingValue /// </summary> /// <param name="domainModel">领域模型</param> /// <param name="instance">数据</param> /// <returns>ShardingValue</returns> private ShardingValue CreateShardingValue(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, object instance) { ShardingValue shardingValue = null; var shardingColumn = domainObject.DataObject.Columns.FirstOrDefault(i => i.IsShardingColumn); if (shardingColumn == null) { throw new Exception("DataObject unset sharding column:" + domainObject.DataObjectID); } var shardingElement = domainObject.Elements.FirstOrDefault(i => i.DataColumnID == shardingColumn.ID); var propValue = ObjectPropertyValueUtils.GetPropValue(shardingElement.PropertyName, instance); switch (shardingElement.DataType) { case ElementDataType.DateTime: case ElementDataType.Date: shardingValue = new ShardingValue(domainModel.Name, shardingElement.ID, Convert.ToDateTime(propValue)); break; case ElementDataType.Integer: shardingValue = new ShardingValue(domainModel.Name, shardingElement.ID, Convert.ToInt64(propValue)); break; case ElementDataType.String: default: shardingValue = new ShardingValue(domainModel.Name, shardingElement.ID, Convert.ToString(propValue)); break; } return(shardingValue); }
/// <summary> /// 构造函数 /// </summary> /// <param name="domainModel">领域模型</param> /// <param name="domainObject">领域对象</param> /// <param name="dbType">数据库类型</param> /// <param name="filterCondition">过滤条件</param> /// <param name="orderByCondition">排序条件</param> public SqlBuildingContext(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, DbType dbType, string filterCondition = "", string orderByCondition = "") : this(domainModel, domainObject, dbType) { FilterCondition = filterCondition; OrderByCondition = orderByCondition; }