private void UpdateObject(Transaction transaction) { int changedCount = 0; int paramCount = this.entity.FieldCount - this.entity.ReadOnlyCount; if (this.initial == InitialState.Unchanged && this.entity.ChangesOnly && this.entity.UpdateSP.Length == 0) { for (int index = 0; index < this.entity.FieldCount; index++) { if (this.entity[index].PersistType == PersistType.Persist && !this.entity.IsKeyMember(this.entity[index].Member)) { if (this.IsDirty(index)) { changedCount++; } else { paramCount--; } } } if (changedCount == 0) return; } Parameter[] parameters = new Parameter[paramCount]; FieldMap[] changedFields = new FieldMap[changedCount]; int paramIndex = 0; int changedIndex = 0; int concurrentIndex = paramCount - 1; for (int index = 0; index < this.entity.FieldCount; index++) { if (this.entity[index].PersistType != PersistType.ReadOnly && !this.entity.IsKeyMember(this.entity[index].Member)) { string name = this.entity[index].Parameter; object nullValue = this.entity[index].NullValue; object value = this.GetField(this.entity[index].Member); if (this.entity[index].PersistType == PersistType.Concurrent) { parameters[concurrentIndex] = new Parameter(name, value, nullValue); concurrentIndex--; } else { // PersistType.Persist if (changedCount == 0 || this.IsDirty(index)) { parameters[paramIndex] = new Parameter(name, value, nullValue); paramIndex++; if (changedCount > 0) { changedFields[changedIndex] = this.entity[index]; changedIndex++; } } } } } FieldMap[] keyFields = this.entity.KeyFields; for (int index = 0; index < keyFields.Length; index++) { string keyName = keyFields[index].Parameter; object keyNullValue = keyFields[index].NullValue; object keyValue = this.GetField(keyFields[index].Member); parameters[paramIndex] = new Parameter(keyName, keyValue, keyNullValue); paramIndex++; } string update; if (changedCount == 0) { update = this.commands.Update; } else { update = this.commands.CreateUpdate(changedFields); } int output = this.context.Connection.TransactionCommand(transaction.id, this.EntityObject.GetType(), CommandInfo.Update, transaction.transaction, update, parameters); if (output <= 0) { throw new PersistenceException("ObjectSpace: Entity Object was not Updated - " + this.entity.Type); } }
// Make sure cascade deletes bubble through all related child collection private void PersistChildren(Transaction transaction, PersistDepth persistDepth, bool parentDeleted) { if (persistDepth == PersistDepth.ObjectGraph) { object[] keyValues = new object[this.entity.KeyFields.Length]; for (int index1 = 0; index1 < this.entity.KeyFields.Length; index1++) { keyValues[index1] = this.GetField(this.entity.KeyFields[index1].Member); } for (int index = 0; index < this.entity.RelationCount; index++) { bool cascadeDelete = (this.State == ObjectState.Deleted) && this.entity.Relation(index).Cascade; if (this.entity.Relation(index).Relationship == Relationship.Child) { EntityMap childMap = this.context.Mappings[this.entity.Relation(index).Type]; string[] childMembers = new string[this.entity.Relation(index).Fields.Length]; for (int index2 = 0; index2 < childMembers.Length; index2++) { for (int field = 0; field < childMap.FieldCount; field++) { if (childMap[field].Field == this.entity.Relation(index).Fields[index2] && childMap[field].PersistType == PersistType.Persist) { childMembers[index2] = childMap[field].Member; break; } } } IList children = (IList)this.GetField(this.entity.Relation(index).Member); // Do not lazy-load lists to persist them -- Jerry Shea (http://www.RenewTek.com) if (!(children is ILoadOnDemand) || (children as ILoadOnDemand).IsLoaded || cascadeDelete || parentDeleted) { // Force recursive persistence if there are more child relations in this graph bool subChildren = (this.context.Mappings[this.entity.Relation(index).Type].ChildRelations > 0); foreach (object entityChild in children) { if (subChildren || cascadeDelete || parentDeleted || this.context[entityChild].State != ObjectState.Unchanged) { if (this.context[entityChild].State == ObjectState.Inserted) { for (int index3 = 0; index3 < childMembers.Length; index3++) { this.context[entityChild].SetField(childMembers[index3], keyValues[index3]); } } if (this.context[entityChild].State != ObjectState.Unknown) { this.context[entityChild].PersistChanges(transaction, persistDepth, cascadeDelete || parentDeleted); } } } BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance; PropertyInfo relation = children.GetType().GetProperty("Removed", flags); if (relation != null) { ArrayList removed = (ArrayList)relation.GetValue(children, null); foreach (object removedChild in removed) { if (this.context[removedChild].State != ObjectState.Unknown) { this.context[removedChild].MarkForDeletion(); this.context[removedChild].PersistChanges(transaction, persistDepth, true); } } removed.Clear(); } } } else if (this.entity.Relation(index).Relationship == Relationship.Many) { ManyMap manyMap = (ManyMap)this.entity.Relation(index); IList children = (IList)this.GetField(manyMap.Member); // Do not lazy-load lists to persist them if (!(children is ILoadOnDemand) || (children as ILoadOnDemand).IsLoaded || cascadeDelete || parentDeleted) { if (manyMap.DeleteSP == null || manyMap.DeleteSP.Length == 0) { string whereClause = this.commands.GetExpression(manyMap.Table, manyMap.Source, keyValues); string sqlDelete = this.commands.CreateDelete(manyMap.Table, whereClause); this.context.Connection.TransactionCommand(transaction.id, this.EntityObject.GetType(), CommandInfo.ManyDelete, transaction.transaction, sqlDelete); } else { Parameter[] parameters = new Parameter[keyValues.Length]; for (int index4 = 0; index4 < keyValues.Length; index4++) { parameters[index4] = new Parameter(manyMap.Source[index4], keyValues[index4], null); } this.context.Connection.TransactionCommand(transaction.id, this.EntityObject.GetType(), CommandInfo.ManyDelete, transaction.transaction, manyMap.DeleteSP, parameters); } if (!(cascadeDelete || parentDeleted)) { // Bug-Fix for Multiple Many-to-Many to Avoid Re-Inserts on Deletes foreach (object entityChild in children) { Instance childInstance = this.context[entityChild]; object childKeys = EntityKey.GetObjectKey(this.context, childInstance); if (manyMap.InsertSP == null || manyMap.InsertSP.Length == 0) { object[] childValues = null; if (childKeys.GetType().IsArray) { childValues = childKeys as object[]; } else { childValues = new object[] { childKeys }; } string sqlInsert = this.commands.InsertMany(manyMap.Table, manyMap.Source, manyMap.Dest, keyValues, childValues); this.context.Connection.TransactionCommand(transaction.id, this.EntityObject.GetType(), CommandInfo.ManyInsert, transaction.transaction, sqlInsert); } else { Parameter[] parameters = new Parameter[2 * keyValues.Length]; for (int index5 = 0; index5 < keyValues.Length; index5++) { parameters[index5] = new Parameter(manyMap.Source[index5], keyValues[index5], null); } if (childKeys.GetType().IsArray) { for (int index6 = keyValues.Length; index6 < 2 * keyValues.Length; index6++) { parameters[index6] = new Parameter(manyMap.Dest[index6], (childKeys as object[])[index6], null); } } else { parameters[keyValues.Length] = new Parameter(manyMap.Dest[0], childKeys, null); } this.context.Connection.TransactionCommand(transaction.id, this.EntityObject.GetType(), CommandInfo.ManyInsert, transaction.transaction, manyMap.InsertSP, parameters); } } } } } } } }
private void DeleteObject(Transaction transaction) { if (this.initial != InitialState.Inserted) { FieldMap[] keyFields = this.entity.KeyFields; Parameter[] parameters = new Parameter[this.entity.ConcurrentCount + keyFields.Length]; int paramIndex = 0; for (int index = 0; index < keyFields.Length; index++) { string keyName = keyFields[index].Parameter; object keyNullValue = keyFields[index].NullValue; object keyValue = this.GetField(keyFields[index].Member); parameters[paramIndex] = new Parameter(keyName, keyValue, keyNullValue); paramIndex++; } for (int index = 0; index < this.entity.FieldCount; index++) { if (this.entity[index].PersistType == PersistType.Concurrent && !this.entity.IsKeyMember(this.entity[index].Member)) { string name = this.entity[index].Parameter; object nullValue = this.entity[index].NullValue; object value = this.GetField(this.entity[index].Member); if (this.entity[index].PersistType == PersistType.Concurrent) { parameters[paramIndex] = new Parameter(name, value, nullValue); paramIndex++; } } } int output = this.context.Connection.TransactionCommand(transaction.id, this.EntityObject.GetType(), CommandInfo.Delete, transaction.transaction, this.commands.Delete, parameters); if (output <= 0) { throw new PersistenceException("ObjectSpace: Entity Object was not Deleted - " + this.entity.Type); } } }
private void InsertObject(Transaction transaction) { EntityMap map = this.entity; FieldMap autoKeyMember = null; int paramCount = map.FieldCount - map.ReadOnlyCount - map.ConcurrentCount; if (map.KeyType == KeyType.Auto) { // autos have one key segment at the end that is an out value... paramCount--; } Parameter[] parameters = new Parameter[paramCount]; int paramIndex = 0; for (int index = 0; index < map.FieldCount; index++) { FieldMap field = map[index]; if (field.PersistType == PersistType.Persist) { if (map.KeyType == KeyType.Auto && map.IsAutoKeyMember(field.Member)) { // skip the final key segment that are auto-assigned but note it autoKeyMember = field; continue; } string name = field.Parameter; object nullValue = field.NullValue; object value = this.GetField(field.Member); parameters[paramIndex] = new Parameter(name, value, nullValue); paramIndex++; } } if (map.KeyType == KeyType.Auto) { object keyValue = this.context.Connection.TransactionScalar(transaction.id, this.EntityObject.GetType(), CommandInfo.Insert, transaction.transaction, this.commands.Insert, parameters); if (keyValue == null) { throw new PersistenceException("ObjectSpace: Entity Object was not Inserted - " + this.entity.Type); } // Tracking Bug-Fix by Gerrod Thomas (http://www.Gerrod.com) this.context.EndTracking(this.EntityObject); this.SetField(autoKeyMember, keyValue); this.context.StartTracking(this); } else { int output = this.context.Connection.TransactionCommand(transaction.id, this.EntityObject.GetType(), CommandInfo.Insert, transaction.transaction, this.commands.Insert, parameters); if (output <= 0) { throw new PersistenceException("ObjectSpace: Entity Object was not Inserted - " + this.entity.Type); } } }
/// Output Parameter Support by Alister McIntyre (http://www.aruspex.com.au) /// <summary>The number of parameters in the parameters collection</summary> /// <param name="parameterName">The name of the parameter to add</param> /// <param name="parameterValue">The value of the parameter</param> /// <param name="direction">The direction of the parameter</param> public int AddParameter(string parameterName, object parameterValue, ParameterDirection direction) { int index = this.parameters.Length; Parameter[] tempParameters = new Parameter[index + 1]; this.parameters.CopyTo(tempParameters, 0); tempParameters[index] = new Parameter(parameterName, parameterValue, null, direction); this.parameters = tempParameters; return index; }