public override void TryCopyBeanIfRemoved(Context context, Action <Bean> Update, Action <Bean> UpdateVariable) { CheckResult result = context.GetCopyBeanIfRemovedResult(this); if (null != result) { result.AddUpdate(Update, UpdateVariable); return; } result = new CheckResult() { Bean = this }; context.AddCopyBeanIfRemovedResult(this, result); if (Name.StartsWith("_")) { // bean 是内部创建的,可能是原来删除的,也可能是合并改名引起的。 if (context.Current.Beans.TryGetValue(RealName, out var _)) { return; } var newb = ShadowCopy(context); newb.RealName = RealName; // 原来是新建的Bean,要使用这个。 context.Current.AddBean(newb); result.Bean = newb; result.AddUpdate(Update, UpdateVariable); return; } // 通过查找当前Schemas来发现RefZero。 if (context.Current.Beans.TryGetValue(Name, out var _)) { return; } var newb2 = ShadowCopy(context); newb2.Deleted = true; context.Current.AddBean(newb2); result.Bean = newb2; result.AddUpdate(Update, UpdateVariable); foreach (var v in Variables.Values) { v.TryCopyBeanIfRemoved(context); } }
/// <summary> /// var可能增加,也可能删除,所以兼容仅判断var.id相同的。 /// 并且和谁比较谁没有关系。 /// </summary> /// <param name="other"></param> /// <returns></returns> public override bool IsCompatible(Type other, Context context, Action <Bean> Update, Action <Bean> UpdateVariable) { if (other == null) { return(false); } if (other is Bean beanOther) { CheckResult result = context.GetCheckResult(beanOther, this); if (null != result) { result.AddUpdate(Update, UpdateVariable); return(true); } result = new CheckResult() { Bean = this }; // result在后面可能被更新。 context.AddCheckResult(beanOther, this, result); List <Variable> Deleteds = new List <Variable>(); foreach (var vOther in beanOther.Variables.Values) { if (Variables.TryGetValue(vOther.Id, out var vThis)) { if (vThis.Deleted) { // bean 可能被多个地方使用,前面比较的时候,创建或者复制了被删除的变量。 // 所以可能存在已经被删除var,这个时候忽略比较就行了。 continue; } if (vOther.Deleted) { if (context.Config.AllowSchemasReuseVariableIdWithSameType && vThis.IsCompatible(vOther, context)) { // 反悔 continue; } // 重用了已经被删除的var。此时vOther.Type也是null。 logger.Error("Not Compatible. bean={0} variable={1} Can Not Reuse Deleted Variable.Id", Name, vThis.Name); return(false); } if (false == vThis.IsCompatible(vOther, context)) { logger.Error("Not Compatible. bean={0} variable={1}", Name, vOther.Name); return(false); } } else { // 新删除或以前删除的都创建一个新的。 Deleteds.Add(new Variable() { Id = vOther.Id, Name = vOther.Name, TypeName = vOther.TypeName, KeyName = vOther.KeyName, ValueName = vOther.ValueName, Type = vOther.Type, Deleted = true, }); } } // 限制beankey的var只能增加,不能减少。 // 如果发生了Bean和BeanKey改变,忽略这个检查。 // 如果没有被真正当作Key,忽略这个检查。 if (IsBeanKey && KeyRefCount > 0 && beanOther.IsBeanKey && beanOther.KeyRefCount > 0) { if (Variables.Count < beanOther.Variables.Count) { logger.Error("Not Compatible. beankey={0} Variables.Count < DB.Variables.Count,Must Be Reduced", Name); return(false); } foreach (var vOther in beanOther.Variables.Values) { if (vOther.Deleted) { // 当作Key前允许删除变量,所以可能存在已经被删除的变量。 continue; } if (false == Variables.TryGetValue(vOther.Id, out var _)) { // 被当作Key以后就不能再删除变量了。 logger.Error("Not Compatible. beankey={0} variable={1} Not Exist", Name, vOther.Name); return(false); } } } if (Deleteds.Count > 0) { Bean newBean = ShadowCopy(context); context.Current.AddBean(newBean); result.Bean = newBean; result.AddUpdate(Update, UpdateVariable); foreach (var vDelete in Deleteds) { vDelete.TryCopyBeanIfRemoved(context); newBean.Variables.Add(vDelete.Id, vDelete); } } return(true); } return(false); }