예제 #1
0
        private static IEnumerable <SPFieldAttribute> EnumerateFieldAttributes(SPModelDescriptor descriptor, Type sourceType, Type implementedType)
        {
            InterfaceMapping mapping = default(InterfaceMapping);

            if (sourceType.IsInterface)
            {
                mapping = implementedType.GetInterfaceMap(sourceType);
            }
            foreach (MemberInfo member in sourceType.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                SPModelFieldAssociationCollection collection      = QueryableFields.EnsureKeyValue(member);
                SPModelFieldAssociationCollection otherCollection = null;
                if (sourceType.IsInterface)
                {
                    MethodInfo lookupMethod = null;
                    if (member.MemberType == MemberTypes.Property)
                    {
                        lookupMethod = ((PropertyInfo)member).GetGetMethod() ?? ((PropertyInfo)member).GetSetMethod();
                    }
                    else if (member.MemberType == MemberTypes.Method)
                    {
                        lookupMethod = (MethodInfo)member;
                    }
                    if (lookupMethod != null)
                    {
                        int pos = Array.IndexOf(mapping.InterfaceMethods, lookupMethod);
                        if (pos >= 0)
                        {
                            MemberInfo mappedMember = mapping.TargetMethods[pos];
                            if (member.MemberType == MemberTypes.Property)
                            {
                                mappedMember = implementedType.GetProperty(mappedMember.Name.Substring(4));
                            }
                            if (mappedMember != null)
                            {
                                otherCollection = QueryableFields.EnsureKeyValue(mappedMember);
                                if (otherCollection.Count > 0)
                                {
                                    foreach (SPModelFieldAssociation value in otherCollection)
                                    {
                                        collection.Add(value);
                                    }
                                }
                            }
                        }
                    }
                }

                SPFieldProvisionMode provisionMode = SPFieldProvisionMode.Default;
                SPModelFieldAssociationCollection basePropertyCollection = null;
                IEnumerable <SPFieldAttribute>    attributes             = member.GetCustomAttributes <SPFieldAttribute>(true);

                if (member.MemberType == MemberTypes.Property)
                {
                    PropertyInfo baseProperty = ((PropertyInfo)member).GetBaseDefinition();
                    if (baseProperty != member)
                    {
                        if (!attributes.Any())
                        {
                            attributes    = baseProperty.GetCustomAttributes <SPFieldAttribute>(false);
                            provisionMode = SPFieldProvisionMode.None;
                        }
                        else
                        {
                            basePropertyCollection = QueryableFields.EnsureKeyValue(baseProperty);
                            provisionMode          = SPFieldProvisionMode.FieldLink;
                        }
                    }
                }
                if (member.DeclaringType != sourceType)
                {
                    provisionMode = SPFieldProvisionMode.FieldLink;
                }
                foreach (SPFieldAttribute attribute in attributes)
                {
                    if (attribute.IncludeInQuery)
                    {
                        PropertyInfo property = null;
                        SPModelQueryPropertyAttribute queryPropertyAttribute = member.GetCustomAttribute <SPModelQueryPropertyAttribute>(false);
                        if (queryPropertyAttribute != null)
                        {
                            property = queryPropertyAttribute.QueryProperty;
                        }
                        SPModelFieldAssociation value = new SPModelFieldAssociation(descriptor, attribute, property);
                        collection.Add(value);
                        if (otherCollection != null)
                        {
                            otherCollection.Add(value);
                        }
                        if (basePropertyCollection != null)
                        {
                            basePropertyCollection.Add(value);
                        }
                        if (property != null)
                        {
                            SPModelFieldAssociationCollection foreignPropertyCollection = QueryableFields.EnsureKeyValue(property);
                            foreignPropertyCollection.Add(new SPModelFieldAssociation(descriptor, attribute, null));
                        }
                    }
                    yield return(attribute.Clone(provisionMode));
                }
            }
        }
        protected override Expression VisitMemberAccess(MemberExpression expression)
        {
            SPModelQueryExpressionScope currentScope = stack.Peek();

            switch (expression.Expression.NodeType)
            {
            case ExpressionType.Parameter:
            case ExpressionType.MemberAccess:
            case ExpressionType.Convert:
            case ExpressionType.Call:
                if (expression.Member.DeclaringType == typeof(ISPModelMetaData))
                {
                    switch (expression.Member.Name)
                    {
                    case "ID":
                        currentScope.Field = SPModelQueryFieldInfo.ID;
                        break;

                    case "UniqueId":
                        currentScope.Field = SPModelQueryFieldInfo.UniqueId;
                        break;

                    case "FileRef":
                        currentScope.Field = SPModelQueryFieldInfo.FileRef;
                        break;

                    case "FileLeafRef":
                        currentScope.Field = SPModelQueryFieldInfo.FileLeafRef;
                        break;

                    case "LastModified":
                        currentScope.Field = SPModelQueryFieldInfo.LastModified;
                        break;

                    case "CheckOutUserID":
                        currentScope.Field = SPModelQueryFieldInfo.CheckOutUserID;
                        break;

                    default:
                        throw new NotSupportedException(String.Format("The member '{0}' is not supported", expression.Member.Name));
                    }
                }
                else if (expression.Member.DeclaringType == typeof(TaxonomyItem) || expression.Member.DeclaringType == typeof(SPPrincipal))
                {
                    switch (expression.Member.Name)
                    {
                    case "Id":
                    case "ID":
                        Visit(expression.Expression);
                        break;

                    default:
                        throw new NotSupportedException(String.Format("The member '{0}' is not supported", expression.Member.Name));
                    }
                }
                else
                {
                    currentScope.MemberType        = expression.Type;
                    currentScope.Member            = expression.Member;
                    currentScope.FieldAssociations = SPModelFieldAssociationCollection.GetByMember(expression.Member);
                }
                break;

            default:
                throw new NotSupportedException(String.Format("The member '{0}' is not supported", expression.Member.Name));
            }
            return(expression);
        }
예제 #3
0
        protected override Expression VisitMemberAccess(MemberExpression expression)
        {
            if (invariantExpression)
            {
                return(base.VisitMemberAccess(expression));
            }
            if (expression.Expression != lambdaParam)
            {
                if (expression.Member.DeclaringType == typeof(ISPModelMetaData) &&
                    ((expression.Expression.NodeType == ExpressionType.Call && ((MethodCallExpression)expression.Expression).Method == typeof(SPModelExtension).GetMethod("GetMetaData") && ((MethodCallExpression)expression.Expression).Arguments[0] == lambdaParam) ||
                     (expression.Expression.NodeType == ExpressionType.Convert && ((UnaryExpression)expression.Expression).Operand == lambdaParam)))
                {
                    // allow non-direct field access on the ISPModelMetaData interface
                }
                else
                {
                    Expression result = base.VisitMemberAccess(expression);
                    if (expression.Member.DeclaringType.IsGenericType && expression.Member.DeclaringType.GetGenericTypeDefinition() == typeof(Nullable <>) && expression.Member.Name == "HasValue")
                    {
                        CamlExpression expr = currentScope.GetExpression(v => Caml.IsNotNull(v.FieldRef));
                        currentScope.Reset();
                        currentScope.Expression = expr;
                    }
                    return(result);
                }
            }

            currentScope.MemberType        = expression.Type;
            currentScope.Member            = expression.Member;
            currentScope.Field             = default(SPModelQueryFieldInfo);
            currentScope.FieldAssociations = null;

            if (expression.Member.DeclaringType == typeof(ISPModelMetaData))
            {
                switch (expression.Member.Name)
                {
                case "ID":
                    currentScope.Field = SPModelQueryFieldInfo.ID;
                    break;

                case "UniqueId":
                    currentScope.Field = SPModelQueryFieldInfo.UniqueId;
                    break;

                case "FileRef":
                    currentScope.Field = SPModelQueryFieldInfo.FileRef;
                    break;

                case "FileLeafRef":
                    currentScope.Field = SPModelQueryFieldInfo.FileLeafRef;
                    break;

                case "LastModified":
                    currentScope.Field = SPModelQueryFieldInfo.LastModified;
                    break;

                case "CheckOutUserID":
                    currentScope.Field = SPModelQueryFieldInfo.CheckOutUserID;
                    break;

                default:
                    throw new NotSupportedException(String.Format("Member '{0}' is not supported", GetMemberFullName(expression.Member)));
                }
            }
            else
            {
                currentScope.FieldAssociations = SPModelFieldAssociationCollection.GetByMember(expression.Member);
                foreach (SPFieldAttribute field in currentScope.FieldAssociations.Fields)
                {
                    if (field.TypeAsString == "TaxonomyFieldType" || field.TypeAsString == "TaxonomyFieldTypeMulti")
                    {
                        builder.TaxonomyFields.Add(field.ListFieldInternalName);
                    }
                }
            }
            if (builder.SelectExpression != null)
            {
                if (currentScope.Field.FieldRef != null)
                {
                    builder.AddSelectProperty(currentScope.Field.FieldRef);
                }
                else if (currentScope.FieldAssociations.Queryable && expression.Member.MemberType == MemberTypes.Property && ((PropertyInfo)expression.Member).GetGetMethod().IsAbstract)
                {
                    builder.AddSelectProperty(currentScope.FieldAssociations.Fields.First().ListFieldInternalName);
                }
                else
                {
                    builder.SelectAllProperties = true;
                }
            }
            return(expression);
        }