SubSonic中的字段付值--MakeOld & Update

    技术2025-01-08  52

      根据设计当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=================

          ///

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

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

            ///

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

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

            ///

            /// Copies the passed-in instance settings to this instance        ///         /// The copy instance.         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======================

            ///

            /// Sets a value for a particular column in the record        ///         /// Name of the column, as defined in the database         /// The value to set the type to         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============

                ///

                /// Gets or sets the current value.            ///             /// The current 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;                }            }

    最新回复(0)