public override object Insert <TEntity>(Expression <Func <TEntity> > content, string table) { PublicHelper.CheckNull(content); TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(typeof(TEntity)); if (typeDescriptor.PrimaryKeys.Count > 1) { /* 对于多主键的实体,暂时不支持调用这个方法进行插入 */ throw new NotSupportedException(string.Format("Can not call this method because entity '{0}' has multiple keys.", typeDescriptor.Definition.Type.FullName)); } PrimitivePropertyDescriptor keyPropertyDescriptor = typeDescriptor.PrimaryKeys.FirstOrDefault(); Dictionary <MemberInfo, Expression> insertColumns = InitMemberExtractor.Extract(content); DbTable dbTable = PublicHelper.CreateDbTable(typeDescriptor, table); DefaultExpressionParser expressionParser = typeDescriptor.GetExpressionParser(dbTable); DbInsertExpression insertExp = new DbInsertExpression(dbTable); object keyVal = null; foreach (var kv in insertColumns) { MemberInfo key = kv.Key; PrimitivePropertyDescriptor propertyDescriptor = typeDescriptor.GetPrimitivePropertyDescriptor(key); if (propertyDescriptor.IsAutoIncrement) { throw new ChloeException(string.Format("Could not insert value into the auto increment column '{0}'.", propertyDescriptor.Column.Name)); } if (propertyDescriptor.HasSequence()) { throw new ChloeException(string.Format("Can not insert value into the column '{0}', because it's mapping member has define a sequence.", propertyDescriptor.Column.Name)); } if (propertyDescriptor.IsPrimaryKey) { object val = ExpressionEvaluator.Evaluate(kv.Value); if (val == null) { throw new ChloeException(string.Format("The primary key '{0}' could not be null.", propertyDescriptor.Property.Name)); } else { keyVal = val; insertExp.InsertColumns.Add(propertyDescriptor.Column, DbExpression.Parameter(keyVal, propertyDescriptor.PropertyType, propertyDescriptor.Column.DbType)); continue; } } insertExp.InsertColumns.Add(propertyDescriptor.Column, expressionParser.Parse(kv.Value)); } foreach (PrimitivePropertyDescriptor propertyDescriptor in typeDescriptor.PrimitivePropertyDescriptors) { if (propertyDescriptor.IsAutoIncrement && propertyDescriptor.IsPrimaryKey) { insertExp.Returns.Add(propertyDescriptor.Column); continue; } if (propertyDescriptor.HasSequence()) { DbMethodCallExpression getNextValueForSequenceExp = PublicHelper.MakeNextValueForSequenceDbExpression(propertyDescriptor, dbTable.Schema); insertExp.InsertColumns.Add(propertyDescriptor.Column, getNextValueForSequenceExp); if (propertyDescriptor.IsPrimaryKey) { insertExp.Returns.Add(propertyDescriptor.Column); } continue; } } if (keyPropertyDescriptor != null) { //主键为空并且主键又不是自增列 if (keyVal == null && !keyPropertyDescriptor.IsAutoIncrement && !keyPropertyDescriptor.HasSequence()) { throw new ChloeException(string.Format("The primary key '{0}' could not be null.", keyPropertyDescriptor.Property.Name)); } } List <DbParam> parameters; this.ExecuteNonQuery(insertExp, out parameters); if (keyPropertyDescriptor != null && (keyPropertyDescriptor.IsAutoIncrement || keyPropertyDescriptor.HasSequence())) { string outputColumnName = Utils.GenOutputColumnParameterName(keyPropertyDescriptor.Column.Name); DbParam outputParam = parameters.Where(a => a.Direction == ParamDirection.Output && a.Name == outputColumnName).First(); keyVal = PublicHelper.ConvertObjectType(outputParam.Value, keyPropertyDescriptor.PropertyType); } return(keyVal); /* It will return null if an entity does not define primary key. */ }
public override TEntity Insert <TEntity>(TEntity entity, string table) { PublicHelper.CheckNull(entity); TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(typeof(TEntity)); DbTable dbTable = PublicHelper.CreateDbTable(typeDescriptor, table); List <PrimitivePropertyDescriptor> outputColumns = new List <PrimitivePropertyDescriptor>(); Dictionary <PrimitivePropertyDescriptor, DbExpression> insertColumns = new Dictionary <PrimitivePropertyDescriptor, DbExpression>(); foreach (PrimitivePropertyDescriptor propertyDescriptor in typeDescriptor.PrimitivePropertyDescriptors) { if (propertyDescriptor.IsAutoIncrement) { outputColumns.Add(propertyDescriptor); continue; } if (propertyDescriptor.HasSequence()) { DbMethodCallExpression getNextValueForSequenceExp = PublicHelper.MakeNextValueForSequenceDbExpression(propertyDescriptor, dbTable.Schema); insertColumns.Add(propertyDescriptor, getNextValueForSequenceExp); outputColumns.Add(propertyDescriptor); continue; } object val = propertyDescriptor.GetValue(entity); PublicHelper.NotNullCheck(propertyDescriptor, val); DbExpression valExp = DbExpression.Parameter(val, propertyDescriptor.PropertyType, propertyDescriptor.Column.DbType); insertColumns.Add(propertyDescriptor, valExp); } DbInsertExpression e = new DbInsertExpression(dbTable); foreach (var kv in insertColumns) { e.InsertColumns.Add(kv.Key.Column, kv.Value); } e.Returns.AddRange(outputColumns.Select(a => a.Column)); List <DbParam> parameters; this.ExecuteNonQuery(e, out parameters); List <DbParam> outputParams = parameters.Where(a => a.Direction == ParamDirection.Output).ToList(); for (int i = 0; i < outputColumns.Count; i++) { PrimitivePropertyDescriptor propertyDescriptor = outputColumns[i]; string putputColumnName = Utils.GenOutputColumnParameterName(propertyDescriptor.Column.Name); DbParam outputParam = outputParams.Where(a => a.Name == putputColumnName).First(); var outputValue = PublicHelper.ConvertObjectType(outputParam.Value, propertyDescriptor.PropertyType); outputColumns[i].SetValue(entity, outputValue); } return(entity); }
protected override async Task <object> Insert <TEntity>(Expression <Func <TEntity> > content, string table, bool @async) { PublicHelper.CheckNull(content); TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(typeof(TEntity)); if (typeDescriptor.PrimaryKeys.Count > 1) { /* 对于多主键的实体,暂时不支持调用这个方法进行插入 */ throw new NotSupportedException(string.Format("Can not call this method because entity '{0}' has multiple keys.", typeDescriptor.Definition.Type.FullName)); } PrimitivePropertyDescriptor keyPropertyDescriptor = typeDescriptor.PrimaryKeys.FirstOrDefault(); Dictionary <MemberInfo, Expression> insertColumns = InitMemberExtractor.Extract(content); DbTable dbTable = PublicHelper.CreateDbTable(typeDescriptor, table); DefaultExpressionParser expressionParser = typeDescriptor.GetExpressionParser(dbTable); DbInsertExpression insertExp = new DbInsertExpression(dbTable); object keyVal = null; foreach (var kv in insertColumns) { MemberInfo key = kv.Key; PrimitivePropertyDescriptor propertyDescriptor = typeDescriptor.GetPrimitivePropertyDescriptor(key); if (propertyDescriptor.IsAutoIncrement) { throw new ChloeException(string.Format("Could not insert value into the identity column '{0}'.", propertyDescriptor.Column.Name)); } if (propertyDescriptor.HasSequence()) { throw new ChloeException(string.Format("Can not insert value into the column '{0}', because it's mapping member has define a sequence.", propertyDescriptor.Column.Name)); } if (propertyDescriptor.IsPrimaryKey) { object val = ExpressionEvaluator.Evaluate(kv.Value); if (val == null) { throw new ChloeException(string.Format("The primary key '{0}' could not be null.", propertyDescriptor.Property.Name)); } else { keyVal = val; insertExp.InsertColumns.Add(propertyDescriptor.Column, DbExpression.Parameter(keyVal)); continue; } } insertExp.InsertColumns.Add(propertyDescriptor.Column, expressionParser.Parse(kv.Value)); } foreach (var item in typeDescriptor.PrimitivePropertyDescriptors.Where(a => a.HasSequence())) { DbMethodCallExpression getNextValueForSequenceExp = PublicHelper.MakeNextValueForSequenceDbExpression(item, dbTable.Schema); insertExp.InsertColumns.Add(item.Column, getNextValueForSequenceExp); } if (keyPropertyDescriptor != null) { //主键为空并且主键又不是自增列 if (keyVal == null && !keyPropertyDescriptor.IsAutoIncrement && !keyPropertyDescriptor.HasSequence()) { throw new ChloeException(string.Format("The primary key '{0}' could not be null.", keyPropertyDescriptor.Property.Name)); } } if (keyPropertyDescriptor == null) { await this.ExecuteNonQuery(insertExp, @async); return(keyVal); /* It will return null if an entity does not define primary key. */ } if (!keyPropertyDescriptor.IsAutoIncrement && !keyPropertyDescriptor.HasSequence()) { await this.ExecuteNonQuery(insertExp, @async); return(keyVal); } insertExp.Returns.Add(keyPropertyDescriptor.Column); IDbExpressionTranslator translator = this.DatabaseProvider.CreateDbExpressionTranslator(); DbCommandInfo dbCommandInfo = translator.Translate(insertExp); object ret = this.Session.ExecuteScalar(dbCommandInfo.CommandText, dbCommandInfo.GetParameters()); if (ret == null || ret == DBNull.Value) { throw new ChloeException("Unable to get the identity/sequence value."); } ret = PublicHelper.ConvertObjectType(ret, typeDescriptor.AutoIncrement.PropertyType); return(ret); }