Inheritance: IAdfQuery
        /// <summary>
        /// Save the specified data of <see cref="IInternalState"/> into database.
        /// </summary>
        /// <param name="query">The <see cref="IAdfQuery"/> that defines the datasource name and query statement.</param>
        /// <param name="data">The data of <see cref="IInternalState"/> that needs to be saved.</param>
        /// <returns>True if data is successfully saved; otherwise, false. 
        /// This method also returns false if <see cref="IAdfQuery"/> or <see cref="IInternalState"/> is null.</returns>
        /// <exception cref="System.InvalidOperationException">The current state of the connection is closed.</exception>
        /// <exception cref="System.Data.DBConcurrencyException">An attempt to execute an INSERT, UPDATE, or DELETE statement resulted in zero records affected.</exception>
        public bool Save(IAdfQuery query, IInternalState data)
        {
            if (query == null) throw new ArgumentNullException("query");
            if (data == null) throw new ArgumentNullException("data");

            if (!data.IsAltered) return true;

            var state = data as DictionaryState;
            if (state == null) throw new InvalidOperationException("State is not a " + typeof(DictionaryState));

            var table = query.Tables[0];

            var q = new AdfQuery()
                .From(table);

            q.QueryType = state.IsNew ? QueryType.Insert : QueryType.Update;

            foreach (var col in state)
            {
                if (col.Key.IsAutoIncrement || col.Key.IsTimestamp) continue;                  // auto increment fields are not saved
                if (col.Key.IsIdentity && !state.IsNew) continue;       // primary key is not saved when object is not new

                q.Selects.Add(new Expression { Column = col.Key, Type = ExpressionType.Column });
                q.Wheres.Add(new Where { Column = col.Key, Parameter = new Parameter(col.Value, ParameterType.QueryParameter) });
            }

            if (!state.IsNew)
            {
                var timestamp = state.Keys.FirstOrDefault(col => col.IsTimestamp);
                if (timestamp == null) throw new InvalidOperationException("Cannot save this state as it does not have a timestamp");

                q
                    .Where(timestamp).IsEqual(state[timestamp])
                    .Where(state.PrimaryKey).IsEqual(state[state.PrimaryKey]);
            }

            return RunSave(state, q);
        }
Example #2
0
        /// <summary>
        /// Create a new data row of <see cref="IInternalState"/> to insert new data into database.
        /// </summary>
        /// <param name="type">Set the specified Type column of SmartReference table.</param>
        /// <returns>The query result into <see cref="IInternalState"/> object.</returns>
        /// <exception cref="System.InvalidOperationException">The current state of the connection is closed.</exception>
        public static IInternalState New(string type)
        {
            var state = new AdfQuery()
                .Select()
                .From(SmartReferenceDescriber.Table)
                .New(DataSource);

            state.ID = IdManager.New<Guid>();

            state.Set(SmartReferenceDescriber.Type, type);

            return state;
        }