private bool IsChildFunction(BuiltInFunctionIDType idType, string parentID, SCConditionCalculatingContext callerContext)
        {
            parentID.CheckStringIsNullOrEmpty("parentID");

            bool   result      = false;
            SCUser currentUser = (SCUser)callerContext.CurrentObject;

            switch (idType)
            {
            case BuiltInFunctionIDType.CodeName:
                result = currentUser.CurrentParents.Exists(p => string.Compare(p.Properties.GetValue("CodeName", string.Empty), parentID, true) == 0);
                break;

            case BuiltInFunctionIDType.Guid:
                result = currentUser.CurrentParentRelations.Exists(r => string.Compare(r.ParentID, parentID, true) == 0);
                break;

            case BuiltInFunctionIDType.FullPath:
            {
                SCObjectAndRelation parent = GetObjectByID(idType, parentID, callerContext);

                if (parent != null)
                {
                    result = currentUser.CurrentParentRelations.Exists(r => string.Compare(r.ParentID, parent.ID, true) == 0);
                }
                break;
            }

            default:
                throw new NotSupportedException(string.Format("不支持的BuiltInFunctionIDType类型{0}", idType));
            }

            return(result);
        }
		private bool IsChildAllFunction(BuiltInFunctionIDType idType, string parentID, SCConditionCalculatingContext callerContext)
		{
			parentID.CheckStringIsNullOrEmpty("parentID");

			bool result = false;
			SCUser currentUser = (SCUser)callerContext.CurrentObject;

			switch (idType)
			{
				case BuiltInFunctionIDType.CodeName:
					result = currentUser.CurrentParents.AllAndNotEmpty(p => string.Compare(p.Properties.GetValue("CodeName", string.Empty), parentID, true) == 0);
					break;
				case BuiltInFunctionIDType.Guid:
					result = currentUser.CurrentParentRelations.AllAndNotEmpty(r => string.Compare(r.ParentID, parentID, true) == 0);
					break;
				case BuiltInFunctionIDType.FullPath:
					{
						SCObjectAndRelation parent = GetObjectByID(idType, parentID, callerContext);

						if (parent != null)
							result = currentUser.CurrentParentRelations.AllAndNotEmpty(r => string.Compare(r.ParentID, parent.ID, true) == 0);
						break;
					}
				default:
					throw new NotSupportedException(string.Format("不支持的BuiltInFunctionIDType类型{0}", idType));
			}

			return result;
		}
        private static SCPropertyAccessorBase GetPropertyAccessor(string funcName, SCConditionCalculatingContext context)
        {
            SCPropertyAccessorBase result = null;

            SchemaNameAndPropertyName snpn = SchemaNameAndPropertyName.FromFullName(funcName);

            snpn.CheckIsValid();

            if (context.PropertyAccessors.TryGetValue(snpn, out result) == false)
            {
                result = new DefaultUsersPropertyAccessor(snpn);
                context.PropertyAccessors.Add(snpn, result);
            }

            return(result);
        }
        private static object CalculateUserFunction(string funcName, ParamObjectCollection arrParams, object callerContext)
        {
            SCConditionCalculatingContext context = (SCConditionCalculatingContext)callerContext;

            object result = null;

            if (SCBuiltInFunctionsCalculator.Instance.IsFunction(funcName))
            {
                //如果是内置函数,则返回内置函数的结果
                result = SCBuiltInFunctionsCalculator.Instance.Calculate(funcName, arrParams, context);
            }
            else
            {
                //根据函数名称,获取属性访问器
                SCPropertyAccessorBase accessor = GetPropertyAccessor(funcName, context);
                result = accessor.GetValue(context, arrParams);
            }

            return(result);
        }
        private bool PropEndWithFunction(string propName, string suffix, SCConditionCalculatingContext callerContext)
        {
            string propValue = callerContext.CurrentObject.Properties.GetValue(propName, string.Empty);

            return(propValue.EndsWith(suffix, StringComparison.OrdinalIgnoreCase));
        }
        private SCObjectAndRelation GetObjectByID(BuiltInFunctionIDType idType, string objectID, SCConditionCalculatingContext callerContext)
        {
            SCCalculatorObjectCache cache = null;

            if (callerContext.ExtendedData.ContainsKey("SCCalculatorObjectCache"))
            {
                cache = (SCCalculatorObjectCache)callerContext.ExtendedData["SCCalculatorObjectCache"];
            }

            if (cache == null)
            {
                cache = new SCCalculatorObjectCache();
                callerContext.ExtendedData.Add("SCCalculatorObjectCache", cache);
            }

            SCObjectAndRelation result = null;

            if (cache.TryGetValue(idType, objectID, out result) == false)
            {
                result = QueryObjectByID(idType, objectID);

                cache.AddObject(idType, objectID, result);
            }

            return(result);
        }
        private bool IsDescendantFunction(BuiltInFunctionIDType idType, string ancestorID, SCConditionCalculatingContext callerContext)
        {
            ancestorID.CheckStringIsNullOrEmpty("ancestorID");

            bool result = false;

            SCObjectAndRelation ancestor = GetObjectByID(idType, ancestorID, callerContext);

            if (ancestor != null)
            {
                result = callerContext.CurrentObject.CurrentParentRelations.Exists(r =>
                                                                                   r.FullPath.IndexOf(ancestor.FullPath, StringComparison.OrdinalIgnoreCase) == 0);
            }

            return(result);
        }
		private bool PropEndWithFunction(string propName, string suffix, SCConditionCalculatingContext callerContext)
		{
			string propValue = callerContext.CurrentObject.Properties.GetValue(propName, string.Empty);

			return propValue.EndsWith(suffix, StringComparison.OrdinalIgnoreCase);
		}
		private SCObjectAndRelation GetObjectByID(BuiltInFunctionIDType idType, string objectID, SCConditionCalculatingContext callerContext)
		{
			SCCalculatorObjectCache cache = null;

			if (callerContext.ExtendedData.ContainsKey("SCCalculatorObjectCache"))
				cache = (SCCalculatorObjectCache)callerContext.ExtendedData["SCCalculatorObjectCache"];

			if (cache == null)
			{
				cache = new SCCalculatorObjectCache();
				callerContext.ExtendedData.Add("SCCalculatorObjectCache", cache);
			}

			SCObjectAndRelation result = null;

			if (cache.TryGetValue(idType, objectID, out result) == false)
			{
				result = QueryObjectByID(idType, objectID);

				cache.AddObject(idType, objectID, result);
			}

			return result;
		}
		private bool IsDescendantFunction(BuiltInFunctionIDType idType, string ancestorID, SCConditionCalculatingContext callerContext)
		{
			ancestorID.CheckStringIsNullOrEmpty("ancestorID");

			bool result = false;

			SCObjectAndRelation ancestor = GetObjectByID(idType, ancestorID, callerContext);

			if (ancestor != null)
				result = callerContext.CurrentObject.CurrentParentRelations.Exists(r =>
					r.FullPath.IndexOf(ancestor.FullPath, StringComparison.OrdinalIgnoreCase) == 0);

			return result;
		}
		private static SCPropertyAccessorBase GetPropertyAccessor(string funcName, SCConditionCalculatingContext context)
		{
			SCPropertyAccessorBase result = null;

			SchemaNameAndPropertyName snpn = SchemaNameAndPropertyName.FromFullName(funcName);

			snpn.CheckIsValid();

			if (context.PropertyAccessors.TryGetValue(snpn, out result) == false)
			{
				result = new DefaultUsersPropertyAccessor(snpn);
				context.PropertyAccessors.Add(snpn, result);
			}

			return result;
		}