//生成语句插入的成员。 private void GenerateForInsertStatementMembers(GenerateContext context, DbNewExpression newitem, QueryBaseFragment source, InsertFragment insert, Func <PropertyInfo, ColumnMetadata> getmember) { int count = 0; foreach (var item in newitem.Members) { count++; insert.CreateMember(null, getmember((PropertyInfo)item.Key)); IMemberFragment member = null; if (_CreateExpressionMethods.TryGetValue(item.Value.ExpressionType, out CreateExpressionDelegate method)) { member = RetrievalMemberForExpression(context, source, item.Value, item.Key, false); } else if (_RetrievalMemberMethods.TryGetValue(item.Value.ExpressionType, out RetrievalMemberDelegate method1)) { member = method1(context, source, item.Value, item.Key, false); } else { throw new NotSupportedException(Res.NotSupportedCreateInsertMember); } if (source.Members.Count != count) { source.Members.Add(member); } } }
/// <summary> /// 使用临时表形式,生成删除若干数据对象(多个主键)语句, /// 要求数据库拥有<see cref="EDbCapable.TemporaryTable"/> /// 和<see cref="EDbCapable.ModifyJoin"/>两个特性。 /// </summary> /// <param name="context">生成上下文。</param> /// <returns>语句片段。</returns> protected virtual SqlFragment GenerateForInsertTempTable(GenerateContext context) { var data = (GenerateDataForInsert)context.Data; var members = data.GetTables().SelectMany(a => a.Members); var createtable = new CreateTempTableFragment(context, members); var temptable = createtable.Table; var insert = new InsertValueFragment(context, temptable, data.CommitObject, data.Items); var mainunit = (CommitKeyUnit)data.MainUnit; mainunit.Keys.ForEach(member => GenerateForInsertMembers(insert, member)); data.CommitObject.Parent = insert; foreach (var unit in data.GetUnits()) { unit.Members.ForEach(member => GenerateForInsertMembers(insert, member)); } var block = new BlockFragment(context, createtable, insert); InsertFragment mainInsert = null; foreach (var unit in data.GetUnits().OfType <CommitKeyUnit>()) { mainInsert = context.Insert(temptable, unit); block.Add(mainInsert); } GenerateForInsertReturnStatement(context, block, mainInsert.Target, temptable); return(block); }
internal static InsertFragment InsertTemptable(this ContentBase data, TemporaryTableFragment temptable, CommitKeyUnit unit, DbName name = null) { var members = unit.Keys.Concat(unit.Members).Select(a => a.Metadata); var context = data.GenerateContext; var table = new TableFragment(context, unit.Table, name); var select = new SelectFragment(context, temptable); var current = new InsertFragment(context, table, select); foreach (var member in members) { select.CreateMember(null, temptable.GetMember(member)); current.CreateMember(null, member); } return(current); }
/// <summary> /// 表达式生成删除语句。 /// </summary> /// <param name="context">生成上下文。</param> /// <param name="content">生成表达式。</param> /// <returns>语句片段。</returns> protected virtual SqlFragment GenerateForDeleteStatement(GenerateContext context, DbExpression content) { var data = (StatementContent)context.Data; var item = data.ItemEpxression; var source = CreateSource(context, content) as QueryBaseFragment; var table = data.Table; if (table.InheritSets.Length == 0) { var target = (TableFragment)GetSource(context, item); target.Name = context.ConvertName(data.TargetName); var delete = new DeleteFragment(context, target) { Where = source.Where, Take = source.Take }; delete.AddSource(source.Sources.Where(a => a != target)); return(delete); } else { var createtable = new CreateTempTableFragment(context, table.Keys); var insert = new InsertFragment(context, createtable.Table, source); insert.Members.AddRange(createtable.Table.Members); foreach (var key in table.Keys) { RetrievalMember(context, source, new DbMemberExpression(key.Member, item), null, false); } var block = new BlockFragment(context, createtable, insert); foreach (var subtable in table.InheritSets.Concat(new TableMetadata[] { table }).Reverse()) { var current = new TableFragment(context, subtable); var delete = new DeleteFragment(context, current); var temptable = new TemporaryTableFragment(context, table.Keys, createtable.Table.Name); current.Join(temptable, table.Keys); delete.AddSource(temptable); block.Add(delete); } return(block); } }
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="content">插入表达式。</param> /// <returns>生成结果。</returns> protected virtual SqlFragment GenerateForInsertStatement(GenerateContext context, DbExpression content) { var data = (StatementContent)context.Data; var newitem = (DbNewExpression)data.ItemEpxression; var source = CreateSource(context, content) as QueryBaseFragment; var metadata = data.Table; if (metadata.InheritSets.Length == 0) { var target = new TableFragment(context, metadata, data.TargetName); var insert = new InsertFragment(context, target, source); GenerateForInsertStatementMembers(context, newitem, source, insert, member => metadata.Members[member]); return(insert); } else { var allsource = metadata.InheritSets.Concat(new TableMetadata[] { metadata }); var allmembers = allsource.SelectMany(a => a.Members).ToDictionary(a => a.Member, a => a); var createtable = new CreateTempTableFragment(context, newitem.Members.Keys.OfType <PropertyInfo>().Select(a => allmembers[a])); var insert = new InsertFragment(context, createtable.Table, source); GenerateForInsertStatementMembers(context, newitem, source, insert, member => allmembers[member]); var block = new BlockFragment(context, createtable, insert); var query = from a in newitem.Members.Keys.OfType <PropertyInfo>().Select(m => allmembers[m]) group a by a.Table into g select new { g.Key, Members = g }; var prefixMembers = query.First().Members.Where(a => a.IsKey); foreach (var g in query) { IEnumerable <ColumnMetadata> currentMembers = g.Members; if (g.Key.InheritSets.Length > 0) { currentMembers = prefixMembers.Concat(g.Members); } var current = new TemporaryTableFragment(context, currentMembers, createtable.Table.Name); block.Add(context.Insert(current, g.Key, currentMembers)); } return(block); } }