/// <inheritdoc/> protected override void WriteFragmentForSourceJoin(SqlWriter writer, ISourceFragment source) { if (source.Join.Value != EJoinType.CrossJoin) { base.WriteFragmentForSourceJoin(writer, source); } }
private void GenerateForInsertReturnStatement(GenerateContext context, BlockFragment block, ISourceFragment target, TemporaryTableFragment temptable) { var data = (GenerateDataForInsert)context.Data; if (data.ReturnMembers.Any()) { if (data.SubUnits != null) { target = new InheritFragment(context, data.Table); } var select = new SelectFragment(context, target); select.Members.AddRange(data.ReturnMembers.Select(a => target.GetMember(a.Metadata))); if (temptable == null) { select.Where = target.JoinCondition(data.CommitObject, data.Table.Keys); } else { var datatable = temptable.Clone(); select.AddSource(datatable); target.Join(datatable, data.Table.Keys); } block.Add(select); } }
/// <summary> /// 写入数据源连接条件。 /// </summary> /// <param name="writer">语句写入器。</param> /// <param name="source">数据源语句。</param> protected virtual void WriteFragmentForSourceCondition(SqlWriter writer, ISourceFragment source) { if (source.Condition != null) { writer.Write(" ON "); source.Condition.WriteSql(writer); } }
/// <summary> /// 根据分组检索表达式初始化查询输出语句及输出对象。 /// </summary> /// <param name="context">生成上下文。</param> /// <param name="current">所在数据源。</param> /// <param name="expression">初始化表达式。</param> /// <param name="parent">父级输出对象。</param> public void InitialRetrieval(GenerateContext context, ISourceFragment current, DbRetrievalFunctionExpression expression, ComplexOutputInfo parent) { if (!_InitialRetrievalMethods.TryGetValue(expression.Function, out InitialRetrievalDelegate method)) { throw new NotSupportedException(string.Format(Res.NotSupportedInitialRetrieval, expression.Function)); } method(context, current, expression, parent); }
/// <summary> /// 创值插入值语句。 /// </summary> /// <param name="context">生成上下文。</param> /// <param name="target">插入目标语句。</param> /// <param name="source">用于插入的提交对象语句块。</param> /// <param name="data">插入的数据集合。</param> public InsertValueFragment(GenerateContext context, ISourceFragment target, CommitObjectFragment source, IEnumerable data) : base(context) { Target = target; Data = data; Source = source; _KeyValues = new Dictionary <ColumnMetadata, ISqlFragment>(); }
/// <summary> /// 创建成员片段。 /// </summary> /// <param name="current">当前数据源片段。</param> /// <param name="property">成员CLR属性。</param> /// <param name="parameter">创建参数。</param> /// <returns>新建成员片段。</returns> public static IMemberFragment CreateMember(this ISourceFragment current, MemberInfo property, object parameter) { var context = current.Context; var generator = context.Generator; var newMember = generator.CreateMember(context, current, property, parameter); current.Members.Add(newMember); return(newMember); }
/// <summary> /// 创建通过主键及值关联的返回数据语句片段。 /// </summary> /// <param name="unit">内容对象。</param> /// <param name="target">目标对象。</param> /// <returns>语句片段。</returns> internal static SelectFragment SelectReturns(this IContentUnit unit, ISourceFragment target) { var data = (ContentBase)unit; var context = data.GenerateContext; var select = new SelectFragment(context, target); select.Members.AddRange(unit.ReturnMembers.Select(a => target.GetMember(a.Metadata))); select.Where = target.JoinCondition(data.CommitObject, data.Table.Keys); return(select); }
/// <summary> /// 注册指定的表达式关联存储语句片段对象。 /// </summary> /// <param name="expression">关联的表达式。</param> /// <param name="source">关联的源对象。</param> /// <param name="isforce">是否强制更新关联数据源。</param> public void RegisterSource(DbExpression expression, ISourceFragment source, bool isforce = false) { if (!_RegistedSource.ContainsKey(expression)) { _RegistedSource.Add(expression, source); } else if (isforce) { _RegistedSource[expression] = source; } }
/// <summary> /// 根据分组检索表达式 Single 初始化查询输出语句及输出对象。 /// </summary> /// <param name="context">生成上下文。</param> /// <param name="current">所在数据源。</param> /// <param name="expression">初始化表达式。</param> /// <param name="parent">父级输出对象。</param> protected virtual void InitialRetrievalForSingle(GenerateContext context, ISourceFragment current, DbRetrievalFunctionExpression expression, ComplexOutputInfo parent) { var select = current as SelectFragment; select.Take = 2; InitialRetrievalForFilter(context, expression, select); if (parent is ObjectOutputInfo output) { output.Option = EObjectOutputOption.OnlyOne; } }
/// <summary> /// 创建通过临时表关联的返回数据语句片段。 /// </summary> /// <param name="unit">内容对象。</param> /// <param name="target">目标对象。</param> /// <param name="temptable">临时表。</param> /// <returns>语句片段。</returns> internal static SelectFragment SelectReturns(this IContentUnit unit, ISourceFragment target, TemporaryTableFragment temptable) { var data = (ContentBase)unit; var context = data.GenerateContext; var select = new SelectFragment(context, target); select.Members.AddRange(unit.ReturnMembers.Select(a => target.GetMember(a.Metadata))); select.AddSource(temptable); target.Join(temptable, data.Table.Keys); return(select); }
/// <summary> /// 写入数据源连接子句 /// </summary> /// <param name="writer">语句写入器。</param> /// <param name="source">目标写入的数据源。</param> protected virtual void WriteFragmentForSourceJoin(SqlWriter writer, ISourceFragment source) { switch (source.Join.Value) { case EJoinType.CrossJoin: writer.Write("CROSS JOIN "); break; case EJoinType.InnerJoin: writer.Write("INNER JOIN "); break; case EJoinType.LeftJoin: writer.Write("LEFT JOIN "); break; case EJoinType.RightJoin: writer.Write("RIGHT JOIN "); break; } }
/// <summary> /// 注册局部表达式关联存储语句片段对象。 /// </summary> /// <param name="expression">关联的表达式。</param> /// <param name="source">关联的源对象。</param> /// <param name="action">执行方法。</param> public void RegisterTempSource(DbExpression expression, ISourceFragment source, Action action) { var contains = _RegistedTempSource.ContainsKey(expression); if (!contains) { _RegistedTempSource.Add(expression, source); } action(); if (!contains) { _RegistedTempSource.Remove(expression); } }
/// <inheritdoc/> protected override void WriteFragmentForSourceCondition(SqlWriter writer, ISourceFragment source) { if (source.Condition != null) { if (source is InheritFragment && source.Join.Value == EJoinType.InnerJoin) { writer.Write(" AND "); } else { writer.Write(" ON "); } source.Condition.WriteSql(writer); } }
//分组检索表达式 ElementAt 实现。 private void InitialRetrievalForElementAtImp(GenerateContext context, ISourceFragment current, DbRetrievalFunctionExpression expression, ComplexOutputInfo parent, EObjectOutputOption option) { var value = expression.Arguments[0] as DbConstantExpression; var select = current as SelectFragment; select.Take = 1; select.Skip = (int)value.Value; if (select.Skip > 0 && select.Sorts.Count == 0) { var member = GetFirstMemberForOrder(select); select.Sorts.Add(new SortFragment(context, member)); } if (parent is ObjectOutputInfo output) { output.Option = option; } }
/// <summary> /// 写入数据源内容。 /// </summary> /// <param name="writer">语句写入器。</param> /// <param name="source">数据源语句。</param> protected virtual void WriteFragmentForSourceContent(SqlWriter writer, ISourceFragment source) { if (source is SelectFragment || source is SetFragment) { writer.Write('('); source.WriteSql(writer); writer.Write(')'); } else { source.WriteSql(writer); } if (!(source is InheritFragment)) { writer.Write(" AS "); writer.Write(source.AliasName); } }
public static InsertFragment Insert(this GenerateContext context, ISourceFragment source, TableMetadata target , IEnumerable <ColumnMetadata> members) { DbName name = null; if (context.Data is ContentBase data) { name = data.TargetName; } var table = new TableFragment(context, target, name); var select = new SelectFragment(context, source); var current = new InsertFragment(context, table, select); foreach (var member in members) { select.CreateMember(null, source.GetMember(member)); current.CreateMember(null, member); } return(current); }
/// <summary> /// 创建删除语句。 /// </summary> /// <param name="context">生成上下文。</param> /// <param name="target">删除目标语句。</param> public DeleteFragment(GenerateContext context, ISourceFragment target) : base(context) { AddSource(target); Target = target; }
/// <summary> /// 根据分组检索表达式 ElementAtDefault 初始化查询输出语句及输出对象。 /// </summary> /// <param name="context">生成上下文。</param> /// <param name="current">所在数据源。</param> /// <param name="expression">初始化表达式。</param> /// <param name="parent">父级输出对象。</param> protected virtual void InitialRetrievalForElementAtDefault(GenerateContext context, ISourceFragment current, DbRetrievalFunctionExpression expression, ComplexOutputInfo parent) { InitialRetrievalForElementAtImp(context, current, expression, parent, EObjectOutputOption.ZeroOrOne); }
/// <summary> /// 生成插入单个数据对象语句,对象的主键是标识列。 /// </summary> /// <param name="context">生成上下文。</param> /// <returns>语句片段。</returns> protected virtual SqlFragment GenerateForInsertIdentitySingle(GenerateContext context) { var getidentity = context.Translate(Expression.Call(null, SupportMembers.DbFunctions.GetIdentity)); var data = (GenerateDataForInsert)context.Data; var identityunit = (CommitIdentityUnit)data.MainUnit; var keyVars = new Dictionary <ColumnMetadata, VariableFragment>(); var identityCreate = new CreateVariableFragment(context, identityunit.Identity.Metadata.Member.PropertyType); keyVars.Add(identityunit.Identity.Metadata, identityCreate.Name); var block = new BlockFragment(context); if (!context.Feature.HasCapable(EDbCapable.ImplicitDeclareVariable)) { block.Add(identityCreate); } var name = data.TargetName; var maintarget = new TableFragment(context, identityunit.Table, name); { var insert = new InsertValueFragment(context, maintarget, data.CommitObject, data.Items); data.CommitObject.Parent = insert; identityunit.Members.ForEach(member => { if (member.Metadata.IsKey && member.ValueType == ECommitValueType.Expression) { var expMember = (CommitExpressionMember)member; var exp = insert.CreateExpression(expMember.Expression); var expVar = new CreateVariableFragment(context, member.Metadata.Member.PropertyType); block.Add(expVar); block.Add(context.Assign(expVar.Name, exp)); keyVars.Add(member.Metadata, expVar.Name); } else { GenerateForInsertMembers(insert, member); } }); block.Add(insert); block.Add(context.Assign(identityCreate.Name, insert.CreateExpression(getidentity))); } if (data.SubUnits != null) { foreach (var unit in data.SubUnits) { var target = new TableFragment(context, unit.Table); var insert = new InsertValueFragment(context, target, data.CommitObject, data.Items); data.CommitObject.Parent = insert; unit.Keys.ForEach(member => { if (keyVars.TryGetValue(member.Metadata, out VariableFragment value)) { insert.SetValue(member.Metadata, value); } else { GenerateForInsertMembers(insert, member); } }); unit.Members.ForEach(member => GenerateForInsertMembers(insert, member)); block.Add(insert); } } if (data.ReturnMembers.Any()) { ISourceFragment target = maintarget; if (data.SubUnits != null) { target = new InheritFragment(context, data.Table); } var select = new SelectFragment(context, target); select.Members.AddRange(data.ReturnMembers.Select(a => target.GetMember(a.Metadata))); select.Where = data.Table.Keys.Select(key => context.Equal(target.GetMember(key), keyVars.ContainsKey(key) ? (IExpressionFragment)keyVars[key] : data.CommitObject.GetMember(key))).Merge(); block.Add(select); } return(block); }
/// <summary> /// 根据类型<see cref="DbScalarFunctionExpression"/>表达式创建表达式语句片段。 /// </summary> /// <param name="context">生成上下文。</param> /// <param name="expression">所在数据源。</param> /// <param name="source">检索表达式。</param> /// <returns>创建结果。</returns> protected virtual IExpressionFragment CreateExpressionForScalarFunction(GenerateContext context, DbExpression expression, ISourceFragment source) { var scalar = (DbScalarFunctionExpression)expression; var result = new ScalarFragment(context) { Function = scalar.Function }; foreach (var arg in scalar.Arguments) { result.Arguments.Add(source.CreateExpression(arg)); } return(result); }
/// <inheritdoc/> protected override IExpressionFragment CreateExpressionForBinary(GenerateContext context, DbExpression expression, ISourceFragment source) { var binary = (DbBinaryExpression)expression; if (binary.Kind == EBinaryKind.Add && binary.ClrType == typeof(string)) { var scalar = new ScalarFragment(context, source.CreateExpression(binary.Left), source.CreateExpression(binary.Right)); scalar.Function = SupportMembers.String.Concat; return(scalar); } return(base.CreateExpressionForBinary(context, expression, source)); }
private void WriteFragmentForCommitReturning(SqlWriter writer, List <IMemberFragment> returnMmebers, ISourceFragment target) { if (returnMmebers.Any()) { var command = target.Context.Data.OperateCommand.GetCustomCommand <IOracleCustomCommand>(); writer.Write(" RETURNING "); returnMmebers.OfType <CommitMemberFragment>().ForEach( () => writer.Write(','), m => { var member = target.GetMember(m.Property); WriteDbName(writer, member.OutputName); }); writer.Write(" INTO "); returnMmebers.OfType <CommitMemberFragment>().ForEach(() => writer.Write(','), m => WriteParameterName(writer, command.AddParameter(m.Metadata))); } }
public static InsertFragment Insert(this GenerateContext context, ISourceFragment source, CommitKeyUnit target) { return(Insert(context, source, target.Table, target.Keys.Concat(target.Members).Select(a => a.Metadata))); }
//生成集合成员虚拟数据源连接。 private void GenerateVirtualJoinForCollectionMember(GenerateContext context, VirtualSourceFragment source, ISourceFragment body, bool iscomposite) { var content = (DbCollectionMemberExpression)source.Expression; var container = source.Container; if (container.IsRecommandLock) { container = container.Parent as SelectFragment; } body.Join = EJoinType.LeftJoin; var pairs = content.Pairs; if (content.Metadata.IsComposite && iscomposite) { pairs = content.CompositePairs; } body.Condition = pairs.Select(a => container.CreateExpression(a)).Merge(); }
/// <summary> /// 根据类型<see cref="DbBinaryExpression"/>表达式创建表达式语句片段。 /// </summary> /// <param name="context">生成上下文。</param> /// <param name="expression">所在数据源。</param> /// <param name="source">检索表达式。</param> /// <returns>创建结果。</returns> protected virtual IExpressionFragment CreateExpressionForBinary(GenerateContext context, DbExpression expression, ISourceFragment source) { var binary = (DbBinaryExpression)expression; if (binary.Kind == EBinaryKind.AndAlso || binary.Kind == EBinaryKind.OrElse) { return(source.CreateExpression(binary.Left).Merge(binary.Kind, source.CreateExpression(binary.Right))); } else { return(new BinaryFragment(context, binary.Kind) { Left = source.CreateExpression(binary.Left), Right = source.CreateExpression(binary.Right) }); } }
/// <summary> /// 创建更新语句。 /// </summary> /// <param name="context">生成上下文。</param> /// <param name="target">更新目标语句。</param> public UpdateFragment(GenerateContext context, ISourceFragment target) : base(context) { Target = target; _KeyValues = new Dictionary <ColumnMetadata, ISqlFragment>(); }
/// <summary> /// 根据类型<see cref="DbUnaryExpression"/>表达式创建表达式语句片段。 /// </summary> /// <param name="context">生成上下文。</param> /// <param name="expression">所在数据源。</param> /// <param name="source">检索表达式。</param> /// <returns>创建结果。</returns> protected virtual IExpressionFragment CreateExpressionForUnary(GenerateContext context, DbExpression expression, ISourceFragment source) { var unary = (DbUnaryExpression)expression; return(new UnaryFragment(context, unary.Kind, unary.Type) { Expresssion = source.CreateExpression(unary.Expression) }); }
private static void SetCommitMembers(this ContentBase data, UpdateFragment update, CommitUnitBase unit, ISourceFragment source = null) { source = source ?? data.CommitObject; foreach (var member in unit.Members) { switch (member.ValueType) { case ECommitValueType.Constant: update.SetValue(member.Metadata, source.GetMember(member.Metadata)); break; case ECommitValueType.Expression: var exp = (CommitExpressionMember)member; update.SetValue(member.Metadata, update.CreateExpression(exp.Expression)); break; } } }
private void OutputReturnMembers(SqlWriter writer, List <IMemberFragment> members, ISourceFragment target = null) { if (members.Count > 0) { writer.WriteLine(); writer.Write("RETURNING "); members.ForEach( () => writer.Write(","), column => { if (target != null) { writer.Write(target.AliasName); writer.Write('.'); } this.WriteDbName(writer, column.OutputName); }); } }
/// <inheritdoc/> protected override IExpressionFragment CreateExpressionForBinary(GenerateContext context, DbExpression expression, ISourceFragment source) { var binary = (DbBinaryExpression)expression; if (binary.Kind == EBinaryKind.Add && binary.ClrType == typeof(string)) { return(new StringConcatFragment(context, source.CreateExpression(binary.Left), source.CreateExpression(binary.Right))); } return(base.CreateExpressionForBinary(context, expression, source)); }