예제 #1
0
        /// <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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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]);
            }
        }