/// <summary> /// options may include: an IDbConnection, an IDbTransaction, CommandBehavior. Save queries should not /// include any other parameters /// </summary> /// <param name="obj"></param> /// <param name="options"></param> /// <returns></returns> public bool Save(object obj, params object[] options) { ParameterParser pp = new ParameterParser("", options); if (pp.Parameters.Count > 0) { throw new IQException("The only allowed parameters for a Save are IDbConnection, IDbTransaction, and CommandBehavior"); } IDBObjectData dbData = IQ.DBData(obj); DBClassInfo info = dbData.ClassInfo; IQEventType eventType = IQEventType.Save; var eventHandler = dbData.IQEventHandlerFunc; if (eventHandler != null) { eventHandler(eventType | IQEventType.Before, dbData); } QueryType queryType = dbData.IsNew() ? QueryType.Insert : QueryType.Update; ISqlQuery query = IQ.CreateQuery(queryType); query.AddFieldMap(info.FieldNameMap); query.TableName = dbData.TableName; bool isDirty = false; bool isNew = dbData.IsNew(); string pk = dbData.ClassInfo.PrimaryKey.Name; foreach (var item in dbData.ClassInfo.FieldInfo) { string name = item.Name; if (!item.IsPrimaryKey && !item.IsReadOnly && (isNew || dbData.IsDirty(name))) { query.AddUpdateData(name, info[name].GetValue(obj)); isDirty = true; } } bool success = false; if (isDirty) { if (queryType == QueryType.Insert) { eventType |= IQEventType.Insert; int newPK = StorageController.RunQueryInsert(pp.Connection, query.GetQuery(), query.Parameters, transaction: pp.Transaction); if (newPK <= 0) { throw new Exception("The record could not be inserted."); } dbData.ClassInfo[pk].SetValue(obj, newPK); success = true; } else { eventType |= IQEventType.Update; query.AddWhereParam(dbData.ClassInfo.PrimaryKey.Name, dbData.ClassInfo.PrimaryKey.GetValue(obj)); success = StorageController.RunQueryScalar(pp.Connection, query.GetQuery(), query.Parameters, transaction: pp.Transaction) > 0; } } else { success = false; } if (eventHandler != null) { eventHandler(eventType | IQEventType.After, dbData); } if (success) { dbData.Clean(); } if (pp.CommandBehavior == CommandBehavior.CloseConnection) { pp.Connection.Close(); } return(success); }