SubSonic中的字段付值MakeOld & Update

  根据设计当MakeOld后(在读取数据库后,或者手动调用),对记录(SubSonic生成的类)属性附值时,Sonic会检测这个Value是否与原来的不同,只有值不同时才会附值成功,并将该列添加到DirtyColumns,而DirtyColumns中的列才会被Update采用,一般情况下 只要所有列中有一个列的是Dirty==true(被更改过),那么在Save时就会采用Update,

注意:SubSonic中判断是否采用Update判断“全部字段集合”中是否存在一个字段被更改,而生成Update命令时使用的集合是DirtyColumns集合,而不是直接从全部字段集合中查找那些被更改的字段,在多数情况下不会出问题,但有些时候可能带来意想不到的问题,参考下面的场境3。

//=============参考代码1================

            public bool IsDirty
            {
                get
                {
                    foreach(TableColumnSetting setting in this)
                    {
                        if(setting.IsDirty)
                            return true;
                    }
                    return false;
                }
                //set
                //{
                //    foreach (TableColumnSetting setting in this)
                //        setting.IsDirty = value;
                //}
            }

//============参考代码2============

     public QueryCommand GetSaveCommand(string userName)
        {
            if(IsNew)
                return GetInsertCommand(userName);

            if(IsDirty)
                return GetUpdateCommand(userName);

            return null;
        }

如果您对记录未做任何更改而直接调用 .Save()时会根据IsNew与IsDirty的取值来决定采用Insert或Update。

如果两个多是false,那么就返回null.那么Save操作将什么都不做。

//============参考代码3============

   QueryCommand cmd = GetSaveCommand(userName);
                if(cmd == null)
                    return;

场境1:

Employe emp=new Employe(1);//加载一个员工数据

//这个时候 IsNew=false,IsDirty=false

emp.Name=emp.Name; //没有改变

emp.Save();//这里的Save方法将不做任何处理

场境2:

Employe emp=new Employe(1);

emp.Name=txtName.txt;//假设您在文本框中调整了Name取值

//这个时候 isNew=false;IsDirty=true;

emp.Save();将使用Update,并且只更新Name字段。

场境3:(报错)

Employe emp=new Employe(1);

Employe backEmp=new Employe();

backEmp.CopyFrom(backEmp);

//copyFrom后会backEmp.IsDirty全部是true

//参考代码7

backEmp.Name="xxxx";

backEmp.MackOld();//将IsNew设置成False

backEmp.Save(); //报错,IsDirty=True,而DirtyColumns为空,

//生成 Update Employe Set Where EmpoyeId=1 这样的错误TSQL

场境4:(报错)

Employe emp=new Employe(1);

Employe backEmp=new Employe();

backEmp.CopyFrom(backEmp);

backEmp.MackOld();

backEmp.Name=backEmp.Name;

backEmp.Save();//这时IsDirty是True,而DirtyColumns为空

正确作法,应该在backEmp.MackOld();后再调用backEmp.MackClear();

//=============参考代码8=================

      /// <summary>
        /// Called after any property is set. Sets IsDirty to <c>true</c>.
        /// </summary>
        public void MarkClean()
        {
            foreach(TableSchema.TableColumnSetting setting in columnSettings)
                setting.IsDirty = false;
            DirtyColumns.Clear();
        }

//========参考代码4==========

        /// <summary>
        /// Called after Update() invokation. Sets IsNew to <c>false</c>.
        /// </summary>
        public void MarkOld()
        {
            IsLoaded = true;
            _isNew = false;
        }

//========参考代码5======================

        /// <summary>
        /// Copies the passed-in instance settings to this instance
        /// </summary>
        /// <param name="copyInstance">The copy instance.</param>
        public void CopyFrom(T copyInstance)
        {
            if(copyInstance == null)
                throw new ArgumentNullException("copyInstance");

            foreach(TableSchema.TableColumnSetting setting in copyInstance.columnSettings)
                SetColumnValue(setting.ColumnName, setting.CurrentValue);
        }

//========参考代码6======================

        /// <summary>
        /// Sets a value for a particular column in the record
        /// </summary>
        /// <param name="columnName">Name of the column, as defined in the database</param>
        /// <param name="oValue">The value to set the type to</param>
        public void SetColumnValue(string columnName, object oValue)
        {
            columnSettings = columnSettings ?? new TableSchema.TableColumnSettingCollection();

            // add the column to the DirtyColumns
            // if this instance has already been loaded
            // and this is a change to existing values
            if(IsLoaded && !IsNew)
            {
                TableSchema.Table schema = GetSchema();
                object oldValue = null;
                string oldValueMsg = "NULL";
                string newValueMsg = "NULL";
                bool areEqualOrBothNull = false;

                try
                {
                    oldValue = columnSettings.GetValue(columnName);
                }
                catch {}

                if(oldValue == null && oValue == null)
                    areEqualOrBothNull = true;
                else
                {
                    if(oldValue != null)
                    {
                        oldValueMsg = oldValue.ToString();
                        areEqualOrBothNull = oldValue.Equals(oValue);
                    }

                    if(oValue != null)
                        newValueMsg = oValue.ToString();
                }

                TableSchema.TableColumn dirtyCol = schema.GetColumn(columnName);

                if(dirtyCol != null && !areEqualOrBothNull)
                {
                    string auditMessage = String.Format("Value changed from {0} to {1}{2}", oldValueMsg, newValueMsg, Environment.NewLine);
                    TableSchema.TableColumn dirtyEntry = DirtyColumns.GetColumn(columnName);
                    if(dirtyEntry != null)
                    {
                        DirtyColumns.Remove(dirtyEntry);
                        auditMessage = String.Concat(dirtyCol.AuditMessage, auditMessage);
                    }

                    dirtyCol.AuditMessage = auditMessage;
                    DirtyColumns.Add(dirtyCol);
                }
            }

            columnSettings.SetValue(columnName, oValue);//这里最终调用参考代码7


        }

//============参考代码7============

            /// <summary>
            /// Gets or sets the current value.
            /// </summary>
            /// <value>The current value.</value>
            public object CurrentValue
            {
                get { return _currentValue; }
                set
                {
                    if(value == null && _currentValue == null)
                        return;

                    if(value != null)
                    {
                        if(value.Equals(_currentValue))
                            return;
                    }

                    _currentValue = value;
                    _isDirty = true;
                }
            }

原文地址:https://www.cnblogs.com/wdfrog/p/1768159.html