实例化类对象及类的属性set方法使用不当


类的属性中set方法操作数据库,新建类对象并给其赋值时总会触发该set方法,而导致不期望的错乱:

库位类Storage,其中传感器状态SensorStatus和逻辑状态LogicStatus有一定的关联关系:

SensorStatus的值变化时,触发该字段的set方法,set方法中会将该库位的LogicStatus也赋同样的值,并更新到数据库。

    public class Storage
    {
        public static ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public Storage()
        {

        }

        public int ID { get; set; }
        public string UpdateBy { get; set; }
        public DateTime UpdateTime { get; set; }
        public string OrderNo { get; set; }
        public int CellNo { get; set; }
        public string StorageNo { get; set; }
        public StorageType StorageType { get; set; }
        public int ItemNo { get; set; }
        public string ItemType { get; set; }
        public int ProductNo { get; set; }
        public string OpcNodeId { get; set; }
        public int Quantity { get; set; }
        public StorageLogicStatus LogicStatus { get; set; }
        private StorageSensorStatus _sensorStatus;
        public StorageSensorStatus SensorStatus
        {
            get { return _sensorStatus; }
            set
            {
                if (value == StorageSensorStatus.Empty)
                {
                    LogicStatus = StorageLogicStatus.Empty;
                    SqlServerUtil.UpdateStorageLogicStatus(StorageNo, StorageLogicStatus.Empty);
                }
                if (value == StorageSensorStatus.Occupied)
                {
                    LogicStatus = StorageLogicStatus.Occupied;
                    SqlServerUtil.UpdateStorageLogicStatus(StorageNo, StorageLogicStatus.Occupied);
                }

                _sensorStatus = value;
            }
        }
    }


而使用时遇到问题:

某个库位的初始状态1:LogicStatus=1;SensorStatus=1

状态2:LogicStatus=3;SensorStatus=1
此时程序执行了下述代码(本意是想获取该库位当前的信息):

Storage storage = SqlServerUtil.GetStorage(targetLocation); //新建一个Storage对象变量,使用数据库查询该库位信息后赋给该变量
        // 获取库位信息  (该方法会实例化Storage对象)
        public static Storage GetStorage(string storageNo)
        {
            string sql = $"Select * From T_Storage Where StorageNo='{storageNo}'";
            return SqlServerBase.Find<Storage>(sql, null);
        }

但给storage赋值的过程中,给字段SensorStatus赋值,触发了其set方法,进而改变了LogicStatus,该变化更新到了数据库中,重新变回状态1:LogicStatus=1;SensorStatus=1

因为数据库的Find方法内部实例化了一个类对象:

        public static T Find<T>(string sql, Object param)
        {
            using (IDbConnection conn = GetConnection())
            {
                T datas = conn.Query<T>(sql, param).SingleOrDefault<T>();
                return datas;
            }
        }

该意外变化导致程序逻辑受到干扰和错乱,目前解决办法为不新建Storage对象,而是只取要用的字段:

int storageItemNo = SqlServerUtil.GetStorageItemNo(targetLocation);
原文地址:https://www.cnblogs.com/zwh1993/p/14750891.html