private IEnumerable <InsertStatement> BuildStatements(IEntityMetadata entity, SchemaMember owner, IEnumerable <SchemaMember> schemas) { var inherits = entity.GetInherits(); foreach (var inherit in inherits) { var statement = new InsertStatement(inherit, owner); foreach (var schema in schemas) { if (!inherit.Properties.Contains(schema.Name)) { continue; } if (schema.Token.Property.IsSimplex) { var simplex = (IEntitySimplexPropertyMetadata)schema.Token.Property; if (simplex.Sequence != null && simplex.Sequence.IsBuiltin) { statement.Sequence = new SelectStatement(owner?.FullPath); statement.Sequence.Select.Members.Add(SequenceExpression.Current(simplex.Sequence.Name, simplex.Name)); } else { var field = statement.Table.CreateField(schema.Token); statement.Fields.Add(field); var parameter = this.IsLinked(owner, simplex) ? Expression.Parameter(schema.Token.Property.Name, simplex.Type) : Expression.Parameter(ParameterExpression.Anonymous, schema, field); statement.Values.Add(parameter); statement.Parameters.Add(parameter); } } else { if (!schema.HasChildren) { throw new DataException($"Missing members that does not specify '{schema.FullPath}' complex property."); } var complex = (IEntityComplexPropertyMetadata)schema.Token.Property; var slaves = this.BuildStatements(complex.Foreign, schema, schema.Children); foreach (var slave in slaves) { slave.Schema = schema; statement.Slaves.Add(slave); } } } yield return(statement); } }
private static IEnumerable <InsertStatement> BuildInserts(IDataMutateContextBase context, IDataEntity entity, SchemaMember owner, IEnumerable <SchemaMember> schemas) { var inherits = entity.GetInherits(); foreach (var inherit in inherits) { var statement = new InsertStatement(inherit, owner); foreach (var schema in schemas) { if (!inherit.Properties.Contains(schema.Name)) { continue; } if (schema.Token.Property.IsSimplex) { var simplex = (IDataEntitySimplexProperty)schema.Token.Property; if (simplex.Sequence != null && simplex.Sequence.IsBuiltin) { statement.Sequence = new SelectStatement(owner?.FullPath); statement.Sequence.Select.Members.Add(SequenceExpression.Current(simplex.Sequence.Name, simplex.Name)); } else { //确认当前成员是否有提供的写入值 var provided = context.Validate(DataAccessMethod.Insert, simplex, out var value); var field = statement.Table.CreateField(schema.Token); statement.Fields.Add(field); var parameter = Utility.IsLinked(owner, simplex) ? ( provided ? Expression.Parameter(schema.Token.Property.Name, simplex.Type, value) : Expression.Parameter(schema.Token.Property.Name, simplex.Type) ) : ( provided ? Expression.Parameter(field, schema, value) : Expression.Parameter(field, schema) ); statement.Values.Add(parameter); statement.Parameters.Add(parameter); } } else { if (!schema.HasChildren) { throw new DataException($"Missing members that does not specify '{schema.FullPath}' complex property."); } //不可变复合属性不支持任何写操作,即在新增操作中不能包含不可变复合属性 if (schema.Token.Property.Immutable) { throw new DataException($"The '{schema.FullPath}' is an immutable complex(navigation) property and does not support the insert operation."); } var complex = (IDataEntityComplexProperty)schema.Token.Property; //注:在构建一对多的导航属性的UPSERT语句时不能指定容器数据(即data参数值为空),因为批量操作语句不支持在构建阶段绑定到具体数据 var upserts = UpsertStatementBuilder.BuildUpserts(context, complex.Foreign, (context.IsMultiple ? null : context.Data), schema, schema.Children); //将新建的语句加入到主语句的从属集中 foreach (var upsert in upserts) { statement.Slaves.Add(upsert); } //var slaves = BuildInserts(context, complex.Foreign, schema, schema.Children); //foreach(var slave in slaves) //{ // slave.Schema = schema; // statement.Slaves.Add(slave); //} } } if (statement.Fields.Count > 0) { yield return(statement); } } }
private IEnumerable <IMutateStatement> BuildStatements(DataInsertContext context, IDataEntity entity, SchemaMember owner, IEnumerable <SchemaMember> schemas) { var inherits = entity.GetInherits(); foreach (var inherit in inherits) { var statement = new InsertStatement(inherit, owner); foreach (var schema in schemas) { if (!inherit.Properties.Contains(schema.Name)) { continue; } if (schema.Token.Property.IsSimplex) { var simplex = (IDataEntitySimplexProperty)schema.Token.Property; if (simplex.Sequence != null && simplex.Sequence.IsBuiltin) { statement.Sequence = new SelectStatement(owner?.FullPath); statement.Sequence.Select.Members.Add(SequenceExpression.Current(simplex.Sequence.Name, simplex.Name)); } else { //确认当前成员是否有提供的写入值 var provided = context.Validate(simplex, out var value); var field = statement.Table.CreateField(schema.Token); statement.Fields.Add(field); var parameter = this.IsLinked(owner, simplex) ? Expression.Parameter(schema.Token.Property.Name, simplex.Type) : ( provided ? Expression.Parameter(field, schema, value) : Expression.Parameter(field, schema) ); statement.Values.Add(parameter); statement.Parameters.Add(parameter); } } else { if (!schema.HasChildren) { throw new DataException($"Missing members that does not specify '{schema.FullPath}' complex property."); } //不可变复合属性不支持任何写操作,即在新增操作中不能包含不可变复合属性 if (schema.Token.Property.Immutable) { throw new DataException($"The '{schema.FullPath}' is an immutable complex(navigation) property and does not support the insert operation."); } var complex = (IDataEntityComplexProperty)schema.Token.Property; var slaves = this.BuildStatements(context, complex.Foreign, schema, schema.Children); foreach (var slave in slaves) { slave.Schema = schema; statement.Slaves.Add(slave); } } } if (statement.Fields.Count > 0) { yield return(statement); } } }