/// <summary> /// Deletes these instances from the database. /// </summary> /// <param name="instances">An array of entities.</param> public static void Delete(EntityBase[] instances) { if (instances == null) { throw new ArgumentNullException("instances"); } if (instances.Length == 0) { return; } Type type = null; Transaction transaction = null; ConditionCollection conditions = new ConditionCollection(); foreach (EntityBase item in instances) { if (item == null) { throw new ArgumentNullException("instance"); } if (type == null) { type = item.GetType(); } else if (type != item.GetType()) { throw new TenorException("You can only have items with the same type."); } if (transaction == null) { transaction = item.tenorTransaction; } else if (transaction != item.tenorTransaction) { throw new TenorException("You can only have items on the same transaction."); } ConditionCollection cc = CreateDeleteConditions(item); if (conditions.Count > 0) { conditions.Add(LogicalOperator.Or); } conditions.Add(cc); } Delete(type, conditions, transaction); }
private static ConditionCollection CreateDeleteConditions(EntityBase instance) { ConditionCollection conditions = new ConditionCollection(); foreach (FieldInfo i in GetFields(instance.GetType())) { if (i.PrimaryKey) { if (conditions.Count != 0) { conditions.Add(LogicalOperator.And); } conditions.Add(i.RelatedProperty.Name, i.PropertyValue(instance)); } } if (conditions.Count == 0) { throw (new Tenor.Data.MissingPrimaryKeyException(instance.GetType())); } return(conditions); }
/// <summary> /// Creates an update query of this entity data. /// </summary> /// <param name="isUpdate">Determines whether to update an existing record or create a new record.</param> /// <param name="parameters">Outputs an array of TenorParameter with required parameters.</param> /// <param name="autoKeyField">Outputs the autonumber FieldInfo.</param> /// <param name="specialValues">The special values can contains sql sentences/sequences/etc</param> /// <param name="connection">The Connection.</param> /// <param name="dialect"></param> /// <returns>Return a SQL query string.</returns> internal string GetSaveSql(bool isUpdate, ConnectionStringSettings connection, System.Collections.Specialized.NameValueCollection specialValues, out FieldInfo autoKeyField, out TenorParameter[] parameters, out GeneralDialect dialect) { Dictionary <FieldInfo, object> data = new Dictionary <FieldInfo, object>(); TableInfo table = TableInfo.CreateTableInfo(this.GetType()); if (connection == null) { connection = table.GetConnection(); } dialect = DialectFactory.CreateDialect(connection); autoKeyField = null; ConditionCollection conditions = new ConditionCollection(); List <FieldInfo> fieldInfos = new List <FieldInfo>(GetFields(this.GetType())); for (int i = fieldInfos.Count - 1; i >= 0; i--) { if (isUpdate && fieldInfos[i].PrimaryKey) { if (conditions.Count != 0) { conditions.Add(LogicalOperator.And); } conditions.Add(fieldInfos[i].RelatedProperty.Name, fieldInfos[i].PropertyValue(this)); if (fieldInfos[i].AutoNumber) { autoKeyField = fieldInfos[i]; data.Add(fieldInfos[i], null); } else { fieldInfos.RemoveAt(i); } } else if (fieldInfos[i].AutoNumber) { autoKeyField = fieldInfos[i]; data.Add(fieldInfos[i], null); } else if (fieldInfos[i].LazyLoading && !propertyData.ContainsKey(fieldInfos[i].RelatedProperty.Name)) { fieldInfos.RemoveAt(i); } else { var lazyValue = fieldInfos[i].PropertyValue(this); if (lazyValue != null && lazyValue.GetType() == typeof(BinaryStream)) { //binary stream will never change fieldInfos.RemoveAt(i); } else { data.Add(fieldInfos[i], lazyValue); } } } string sql = dialect.CreateSaveSql(this.GetType(), data, specialValues, conditions, out parameters) + dialect.LineEnding; if (dialect.GetIdentityOnSameCommand && !isUpdate && autoKeyField != null) { string queryFormat = @"{0} {1} {2}"; string before = string.Empty; if (!string.IsNullOrEmpty(dialect.IdentityBeforeQuery)) { before = dialect.IdentityBeforeQuery + dialect.LineEnding; } string after = string.Empty; if (!string.IsNullOrEmpty(dialect.IdentityAfterQuery)) { after = string.Format(dialect.IdentityAfterQuery, autoKeyField.InsertSQL) + dialect.LineEnding; } sql = string.Format(queryFormat, before, sql, after); } return(sql); }
/// <summary> /// Gets the value of a lazy tagged property. /// This call can do a database access. /// </summary> internal virtual object GetPropertyValue(string propertyName, bool forceGetBinary) { //only loads if not loaded yet. //TODO: provide a way to reload from database. lock (propertyData) { if (forceGetBinary || !propertyData.ContainsKey(propertyName)) { //Getting class metadata. TableInfo table = TableInfo.CreateTableInfo(this.GetType()); System.Reflection.PropertyInfo fieldP = this.GetType().GetProperty(propertyName); if (fieldP == null) { throw new Tenor.Data.MissingFieldException(this.GetType(), propertyName); } ForeignKeyInfo fkInfo = null; fkInfo = ForeignKeyInfo.Create(fieldP); if (fkInfo != null) { // this is an FK, so, route to fk loading return(LoadForeign(fieldP, null)); } else { //Continue to the lazy property (lazy fields like byte[]) loading FieldInfo field = FieldInfo.Create(fieldP); if (field == null) { throw new Tenor.Data.MissingFieldException(this.GetType(), fieldP.Name); } if (!forceGetBinary && (field.FieldType == typeof(BinaryStream) || field.FieldType == typeof(BinaryStream).BaseType)) { propertyData[propertyName] = new BinaryStream(this, propertyName); } else { GeneralDialect dialect = DialectFactory.CreateDialect(table.GetConnection()); ConditionCollection conditions = new ConditionCollection(); foreach (FieldInfo f in GetFields(this.GetType(), true)) { conditions.Add(f.RelatedProperty.Name, f.PropertyValue(this)); } if (conditions.Count == 0) { throw (new Tenor.Data.MissingPrimaryKeyException(this.GetType())); } TenorParameter[] parameters = null; string fieldsPart = dialect.CreateSelectSql(table.RelatedTable, null, new FieldInfo[] { field }, null, null); string wherePart = dialect.CreateWhereSql(conditions, table.RelatedTable, null, out parameters); string sql = dialect.CreateFullSql(table.RelatedTable, false, false, 0, fieldsPart, null, null, wherePart); Tenor.Diagnostics.Debug.DebugSQL("GetPropertyValue()", sql, parameters, table.GetConnection()); #if DEBUG LastSearches.Push(sql); #endif Tenor.Data.DataTable rs = new Tenor.Data.DataTable(sql, parameters, table.GetConnection()); rs.Bind(); if (rs.Rows.Count == 0) { throw (new RecordNotFoundException()); } else if (rs.Rows.Count > 1) { throw new ManyRecordsFoundException(); } else { var obj = rs.Rows[0][field.DataFieldName]; if (obj == DBNull.Value) { obj = null; } if (forceGetBinary) { if (obj == null) { return new byte[] { } } ; else { return(obj); } } else { propertyData[propertyName] = obj; } } } } } return(propertyData[propertyName]); } }