示例#1
0
        /// <summary>
        /// Tries to save the object
        /// </summary>
        /// <param name="obj">The object to save</param>
        /// <param name="criteria">The criteria of type <see cref="Zonkey.UpdateCriteria"/>.</param>
        /// <param name="affect">The <see cref="Zonkey.UpdateAffect"/> value that determines which rows to affect.</param>
        /// <param name="selectBack">The <see cref="Zonkey.SelectBack"/> value that determines whether to select back the changed rows.</param>
        /// <returns>A value of type <see cref="Zonkey.SaveResult"/></returns>
        public SaveResult TrySave(T obj, UpdateCriteria criteria, UpdateAffect affect, SelectBack selectBack)
        {
            var objSV = obj as ISavable;

            if (objSV == null)
            {
                throw new ArgumentException("Save() is only supported on classes that implement Zonkey.ObjectModel.ISavable", "obj");
            }

            var objDCX = obj as DataClass;

            // raise pre-save event
            if (objDCX != null)
            {
                objDCX.OnBeforeSave();
            }

            SaveResult result;

            switch (objSV.DataRowState)
            {
            case DataRowState.Added:
                result = TryInsert(obj, selectBack);

                _lastSaveSuccessType = 1;
                break;

            case DataRowState.Detached:
                throw new InvalidOperationException("Cannot save objects in a detached state. Did you forget to use the new record constructor?");

            case DataRowState.Modified:
                if (((selectBack == SelectBack.None) || (selectBack == SelectBack.AllFields)) &&
                    (criteria <= UpdateCriteria.ChangedFields) && (affect == UpdateAffect.ChangedFields))
                {
                    result = TryUpdate2(obj, criteria, (selectBack == SelectBack.AllFields));
                }
                else
                {
                    result = TryUpdate(obj, criteria, affect, selectBack);
                }

                _lastSaveSuccessType = 2;
                break;

            default:
                return(SaveResult.Skipped);
            }

            // raise post-save event and commit values
            if (result == SaveResult.Success)
            {
                if (objDCX != null)
                {
                    objDCX.OnAfterSave(true);
                }
                objSV.CommitValues();
            }

            return(result);
        }
示例#2
0
 /// <summary>
 /// Tries to update the specified object
 /// </summary>
 /// <param name="obj">The object.</param>
 /// <param name="criteria">The criteria of type <see cref="Zonkey.UpdateCriteria"/>.</param>
 /// <param name="affect">The <see cref="Zonkey.UpdateAffect"/> value that determines which rows to affect.</param>
 /// <param name="selectBack">The <see cref="Zonkey.SelectBack"/> value that determines whether to select back the changed rows.</param>
 /// <returns>A <see cref="Zonkey.SaveResult"/> value based on the outcome of the update operation.</returns>
 public SaveResult TryUpdate(T obj, UpdateCriteria criteria, UpdateAffect affect, SelectBack selectBack)
 {
     try
     {
         DbCommand[] commands = CommandBuilder.GetUpdateCommands(obj, criteria, affect, selectBack);
         return(UpdateInternal(obj, commands, (selectBack != SelectBack.None)));
     }
     catch (DataException) { throw; }
     catch (Exception ex)
     {
         throw new DataException(ex.Message, ex);
     }
 }
示例#3
0
 /// <summary>
 /// Saves the specified object
 /// </summary>
 /// <param name="obj">The object to save</param>
 /// <param name="criteria">The criteria of type <see cref="Zonkey.UpdateCriteria"/>.</param>
 /// <param name="affect">The <see cref="Zonkey.UpdateAffect"/> value that determines which rows to affect.</param>
 /// <param name="selectBack">The <see cref="Zonkey.SelectBack"/> value that determines whether to select back the changed rows.</param>
 /// <returns>true/false</returns>
 public bool Save(T obj, UpdateCriteria criteria, UpdateAffect affect, SelectBack selectBack)
 {
     return(HandleSaveResult(TrySave(obj, criteria, affect, selectBack)));
 }
示例#4
0
        /// <summary>
        /// Saves the collection.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="criteria">The criteria of type <see cref="Zonkey.UpdateCriteria"/>.</param>
        /// <param name="affect">The <see cref="Zonkey.UpdateAffect"/> value that determines which rows to affect.</param>
        /// <param name="selectBack">The <see cref="Zonkey.SelectBack"/> value that determines whether to select back the changed rows.</param>
        /// <returns>A value of type <see cref="T:Zonkey.CollectionSaveResult"/></returns>
        public CollectionSaveResult <T> TrySaveCollection(ICollection <T> collection, UpdateCriteria criteria, UpdateAffect affect, SelectBack selectBack)
        {
            var colResult = new CollectionSaveResult <T>();

            var bindCol = collection as ITrackDeletedItems <T>;

            if (bindCol != null)
            {
                foreach (T obj in bindCol.DeletedItems)
                {
                    var objSV = obj as ISavable;
                    if (objSV != null)
                    {
                        if (objSV.DataRowState == DataRowState.Deleted)
                        {
                            DeleteItem(obj);
                            colResult.Deleted.Add(obj);
                        }
                        else
                        {
                            colResult.Skipped.Add(obj);
                        }
                    }
                    else
                    {
                        colResult.Failed.Add(obj);
                    }
                }
            }

            foreach (T obj in collection)
            {
                var objSV = obj as ISavable;
                if (objSV != null)
                {
                    if (objSV.DataRowState != DataRowState.Unchanged)
                    {
                        switch (TrySave(obj, criteria, affect, selectBack))
                        {
                        case SaveResult.Skipped:
                            colResult.Skipped.Add(obj);
                            break;

                        case SaveResult.Conflict:
                            colResult.Conflicted.Add(obj);
                            break;

                        case SaveResult.Fail:
                            colResult.Failed.Add(obj);
                            break;

                        case SaveResult.Success:
                            if (_lastSaveSuccessType == 1)
                            {
                                colResult.Inserted.Add(obj);
                            }
                            else
                            {
                                colResult.Updated.Add(obj);
                            }

                            break;
                        }
                    }
                    else
                    {
                        colResult.Skipped.Add(obj);
                    }
                }
                else
                {
                    colResult.Failed.Add(obj);
                }
            }

            return(colResult);
        }
示例#5
0
        /// <summary>
        /// Saves the collection.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="criteria">The criteria.</param>
        /// <param name="affect">The affect.</param>
        /// <param name="selectBack">The select back.</param>
        /// <returns></returns>
        public int SaveCollection(ICollection <T> collection, UpdateCriteria criteria, UpdateAffect affect, SelectBack selectBack)
        {
            var result = TrySaveCollection(collection, criteria, affect, selectBack);

            if ((result.Conflicted.Count > 0) || (result.Failed.Count > 0))
            {
                throw new CollectionSaveException <T>(result);
            }

            return(result.Inserted.Count + result.Updated.Count);
        }
示例#6
0
        public DbCommand[] GetUpdateCommands(object obj, UpdateCriteria criteria, UpdateAffect affect, SelectBack selectBack)
        {
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }

            if (obj.GetType() != _dataObjectType)
            {
                throw new ArgumentException("Type of 'obj' does not match type from constructor.");
            }

            // set update criteria - default is changed fields
            if (criteria == UpdateCriteria.Default)
            {
                criteria = (_dataMap.DataItem.UpdateCriteria == UpdateCriteria.Default)
                               ? UpdateCriteria.ChangedFields : _dataMap.DataItem.UpdateCriteria;
            }
            if ((criteria == UpdateCriteria.KeyAndVersion) && (!_dialect.SupportsRowVersion))
            {
                criteria = UpdateCriteria.ChangedFields;
            }

            // set select back default
            if (selectBack == SelectBack.Default)
            {
                selectBack = (_dataMap.DataItem.SelectBack == SelectBack.Default)
                                 ? SelectBack.UnchangedFields : _dataMap.DataItem.SelectBack;
            }

            // get savable obj
            var objSV = obj as ISavable;

            if (objSV == null)
            {
                affect = UpdateAffect.AllFields;

                if (selectBack == SelectBack.UnchangedFields)
                {
                    selectBack = SelectBack.AllFields;
                }

                if (criteria == UpdateCriteria.ChangedFields)
                {
                    criteria = UpdateCriteria.KeyOnly;
                }
            }

            // init command array
            DbCommand updateCommand = GetTextCommand("");

            // create string builders and param lists
            var setString   = new StringBuilder();
            var setParmList = new List <DbParameter>();

            var whereString   = new StringBuilder();
            var whereParmList = new List <DbParameter>();

            var selectString = new StringBuilder();
            var keyString    = new StringBuilder();
            var keyParmList  = new List <DbParameter>();

            foreach (IDataMapField field in _dataMap.DataFields)
            {
                PropertyInfo pi = field.Property;
                if (pi == null)
                {
                    continue;
                }

                bool   hasChanged  = (objSV != null) ? HasFieldChanged(pi, objSV) : true;
                string sFieldDescr = _dialect.FormatFieldName(field.FieldName, (field.UseQuotedIdentifier ?? UseQuotedIdentifier));

                if (selectBack > SelectBack.None)
                {
                    if (field.IsKeyField)
                    {
                        DbParameter keyParam = CreateWhereParam(updateCommand, field);
                        if (keyString.Length > 0)
                        {
                            keyString.Append(" AND ");
                        }
                        keyString.Append(sFieldDescr);
                        keyString.Append(" = ");
                        keyString.Append(keyParam.ParameterName);


                        keyParam.Value = pi.GetValue(obj, null);
                        keyParmList.Add(keyParam);
                    }
                    else if ((selectBack == SelectBack.AllFields) ||
                             ((selectBack == SelectBack.UnchangedFields) && (!hasChanged)) ||
                             ((selectBack >= SelectBack.IdentityOrVersion) && (field.IsRowVersion)))
                    {
                        if (selectString.Length > 0)
                        {
                            selectString.Append(", ");
                        }
                        selectString.Append(sFieldDescr);
                    }
                }

                if (field.IsKeyField ||
                    (hasChanged && (criteria >= UpdateCriteria.ChangedFields)) ||
                    (field.IsRowVersion && (criteria == UpdateCriteria.KeyAndVersion))
                    )
                {
                    // A primary key or row version
                    if (whereString.Length > 0)
                    {
                        whereString.Append(" AND ");
                    }

                    // get value for parameter
                    object oParmValue;
                    if ((objSV != null) && (objSV.OriginalValues.ContainsKey(pi.Name)))
                    {
                        oParmValue = (objSV.OriginalValues[pi.Name] ?? DBNull.Value);
                    }
                    else
                    {
                        oParmValue = (pi.GetValue(obj, null) ?? DBNull.Value);
                    }

                    // add to command
                    if (Convert.IsDBNull(oParmValue))
                    {
                        whereString.AppendFormat("{0} IS NULL", sFieldDescr);
                    }
                    else if (!field.IsComparable)
                    {
                        whereString.AppendFormat("{0} IS NOT NULL", sFieldDescr);
                    }
                    else
                    {
                        DbParameter whereParam = CreateWhereParam(updateCommand, field);
                        whereString.Append(sFieldDescr);
                        whereString.Append(" = ");
                        whereString.Append(whereParam.ParameterName);

                        whereParam.Value = oParmValue;
                        whereParmList.Add(whereParam);
                    }
                }

                if ((field.IsAutoIncrement) || (field.IsRowVersion) || (field.AccessType == AccessType.ReadOnly))
                {
                    continue;
                }
                if ((affect == UpdateAffect.ChangedFields) && (!hasChanged))
                {
                    continue;
                }

                if (setString.Length > 0)
                {
                    setString.Append(", ");
                }

                DbParameter setParm = CreateSetParam(updateCommand, field);
                setString.Append(sFieldDescr);
                setString.Append(" = ");
                setString.Append(setParm.ParameterName);

                setParm.Value = (pi.GetValue(obj, null) ?? DBNull.Value);
                setParmList.Add(setParm);
            }
            if (setParmList.Count == 0)
            {
                return(null);
            }

            if (whereString.Length == 0)
            {
                throw new InvalidOperationException(String.Format("Class '{0}' does not contain any properties with DataFieldAttributes or none are marked with IsKeyField.", _dataObjectType.FullName));
            }

            updateCommand.CommandText = String.Format("UPDATE {0} SET {1} WHERE {2};", SaveToTable, setString, whereString);
            updateCommand.Parameters.AddRange(setParmList.ToArray());
            updateCommand.Parameters.AddRange(whereParmList.ToArray());

            if ((selectBack > SelectBack.None) && (selectString.Length > 0))
            {
                if (keyString.Length == 0)
                {
                    throw new InvalidOperationException(String.Format("Class '{0}' does not contain any properties with DataFieldAttributes or none are marked with IsKeyField.", _dataObjectType.FullName));
                }

                DbCommand selectCommand = GetTextCommand("");
                selectCommand.CommandText = String.Format("SELECT {0} FROM {1} WHERE {2};", selectString, TableName, keyString);
                selectCommand.Parameters.AddRange(keyParmList.ToArray());

                return(new[] { updateCommand, selectCommand });
            }

            // return null index 1 to indicate no select-back
            return(new[] { updateCommand, null });
        }
 /// <summary>
 /// Equivalent to calling DataClassAdapter.Save
 /// </summary>
 /// <typeparam name="Tdc">The type of the dc.</typeparam>
 /// <param name="obj">The obj.</param>
 /// <param name="updateCriteria">The update criteria</param>
 /// <param name="updateAffect">Affect which fields</param>
 /// <param name="selectBack">Select what back</param>
 /// <returns></returns>
 public virtual bool Save <Tdc>(Tdc obj, UpdateCriteria updateCriteria, UpdateAffect updateAffect, SelectBack selectBack)
     where Tdc : class, ISavable, new()
 {
     return(Adapter <Tdc>().Save(obj, updateCriteria, updateAffect, selectBack));
 }
示例#8
0
        /// <summary>
        /// Saves the collection.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="criteria">The criteria of type <see cref="Zonkey.UpdateCriteria"/>.</param>
        /// <param name="affect">The <see cref="Zonkey.UpdateAffect"/> value that determines which rows to affect.</param>
        /// <param name="selectBack">The <see cref="Zonkey.SelectBack"/> value that determines whether to select back the changed rows.</param>
        /// <param name="continueOnError">if set to <c>true</c> continues past errors.</param>
        /// <returns>
        /// A value of type <see cref="Zonkey.CollectionSaveResult{T}"/>
        /// </returns>
        public CollectionSaveResult <T> TrySaveCollection(ICollection <T> collection, UpdateCriteria criteria, UpdateAffect affect, SelectBack selectBack, bool continueOnError)
        {
            var colResult = new CollectionSaveResult <T>();

            var bindCol = collection as ITrackDeletedItems <T>;

            if (bindCol != null)
            {
                foreach (T obj in bindCol.DeletedItems)
                {
                    var objSV = obj as ISavable;
                    if (objSV != null)
                    {
                        if (objSV.DataRowState == DataRowState.Deleted)
                        {
                            try
                            {
                                DeleteItem(obj);
                            }
                            catch (Exception ex)
                            {
                                colResult.Exceptions.Add(new CollectionSaveExceptionItem <T>(obj, ex));
                                if (!continueOnError)
                                {
                                    throw;
                                }
                            }

                            colResult.Deleted.Add(obj);
                        }
                        else
                        {
                            colResult.Skipped.Add(obj);
                        }
                    }
                    else
                    {
                        colResult.Failed.Add(obj);
                    }
                }
            }

            foreach (T obj in collection)
            {
                var objSV = obj as ISavable;
                if (objSV != null)
                {
                    if (objSV.DataRowState != DataRowState.Unchanged)
                    {
                        try
                        {
                            SaveResult saveResult = TrySave(obj, criteria, affect, selectBack);
                            switch (saveResult.Status)
                            {
                            case SaveResultStatus.Skipped:
                                colResult.Skipped.Add(obj);
                                break;

                            case SaveResultStatus.Conflict:
                                colResult.Conflicted.Add(obj);
                                break;

                            case SaveResultStatus.Fail:
                                colResult.Failed.Add(obj);
                                break;

                            case SaveResultStatus.Success:
                                if (saveResult.SaveType == SaveType.Insert)
                                {
                                    colResult.Inserted.Add(obj);
                                }
                                else
                                {
                                    colResult.Updated.Add(obj);
                                }

                                break;
                            }
                        }
                        catch (Exception ex)
                        {
                            colResult.Exceptions.Add(new CollectionSaveExceptionItem <T>(obj, ex));
                            if (!continueOnError)
                            {
                                throw;
                            }
                        }
                    }
                    else
                    {
                        colResult.Skipped.Add(obj);
                    }
                }
                else
                {
                    colResult.Failed.Add(obj);
                }
            }

            return(colResult);
        }
示例#9
0
 /// <summary>
 /// Saves the collection.
 /// </summary>
 /// <param name="collection">The collection.</param>
 /// <param name="criteria">The criteria of type <see cref="Zonkey.UpdateCriteria"/>.</param>
 /// <param name="affect">The <see cref="Zonkey.UpdateAffect"/> value that determines which rows to affect.</param>
 /// <param name="selectBack">The <see cref="Zonkey.SelectBack"/> value that determines whether to select back the changed rows.</param>
 /// <returns>A value of type <see cref="Zonkey.CollectionSaveResult{T}"/></returns>
 public CollectionSaveResult <T> TrySaveCollection(ICollection <T> collection, UpdateCriteria criteria, UpdateAffect affect, SelectBack selectBack)
 {
     return(TrySaveCollection(collection, UpdateCriteria.Default, UpdateAffect.ChangedFields, SelectBack.Default, false));
 }