/// <summary>
        /// Analyzes a lambda expression to check whether it can be satisfied with
        /// $select and client-side materialization.
        /// </summary>
        /// <param name="le">Lambda expression.</param>
        /// <param name="re">Resource expression in scope.</param>
        /// <param name="matchMembers">Whether member accesses are matched as top-level projections.</param>
        /// <param name="context">Context of expression to analyze.</param>
        /// <returns>true if the lambda is a client-side projection; false otherwise.</returns>
        internal static bool Analyze(LambdaExpression le, ResourceExpression re, bool matchMembers, DataServiceContext context)
        {
            Debug.Assert(le != null, "le != null");

            if (le.Body.NodeType == ExpressionType.Constant)
            {
                if (ClientTypeUtil.TypeOrElementTypeIsEntity(le.Body.Type))
                {
                    throw new NotSupportedException(Strings.ALinq_CannotCreateConstantEntity);
                }

                re.Projection = new ProjectionQueryOptionExpression(le.Body.Type, le, new List <string>());
                return(true);
            }

            if (le.Body.NodeType == ExpressionType.MemberInit || le.Body.NodeType == ExpressionType.New)
            {
                AnalyzeResourceExpression(le, re, context);
                return(true);
            }

            if (matchMembers)
            {
                // Members can be projected standalone or type-casted.
                Expression withoutConverts = SkipConverts(le.Body);
                if (withoutConverts.NodeType == ExpressionType.MemberAccess)
                {
                    AnalyzeResourceExpression(le, re, context);
                    return(true);
                }
            }

            return(false);
        }
Пример #2
0
            internal override Expression VisitMemberAccess(MemberExpression m)
            {
                PropertyInfo info;
                Expression   expression;
                Type         type = m.Expression.Type;

                this.leafExpressionIsMemberAccess = true;
                if (PrimitiveType.IsKnownNullableType(type))
                {
                    this.leafExpressionIsMemberAccess = false;
                    return(base.VisitMemberAccess(m));
                }
                if (ProjectionAnalyzer.IsCollectionProducingExpression(m.Expression))
                {
                    throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjection(this.type, m.ToString()));
                }
                if (!ResourceBinder.PatternRules.MatchNonPrivateReadableProperty(m, out info, out expression))
                {
                    throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjection(this.type, m.ToString()));
                }
                Expression expression2 = base.VisitMemberAccess(m);

                if (ClientTypeUtil.TypeOrElementTypeIsEntity(type))
                {
                    Type type2;
                    ResourceBinder.StripTo <Expression>(m.Expression, out type2);
                    this.box.AppendPropertyToPath(info, type2, this.context);
                    this.leafExpressionIsMemberAccess = false;
                }
                return(expression2);
            }
        /// <summary>
        /// Materializes the primitive data values in the given list of <paramref name="values"/>.
        /// </summary>
        /// <param name="actualType">Actual type for properties being materialized.</param>
        /// <param name="values">List of values to materialize.</param>
        /// <param name="undeclaredPropertyBehavior">
        /// Whether properties missing from the client types should be supported or throw exception.
        /// </param>
        /// <remarks>
        /// Values are materialized in-place with each <see cref="ODataProperty"/>
        /// instance.
        /// </remarks>
        internal void MaterializeDataValues(ClientTypeAnnotation actualType, IEnumerable <ODataProperty> values, UndeclaredPropertyBehavior undeclaredPropertyBehavior)
        {
            Debug.Assert(actualType != null, "actualType != null");
            Debug.Assert(values != null, "values != null");

            foreach (var odataProperty in values)
            {
                if (odataProperty.Value is ODataStreamReferenceValue)
                {
                    continue;
                }

                string propertyName = odataProperty.Name;

                var property = actualType.GetProperty(propertyName, undeclaredPropertyBehavior); // may throw
                if (property == null)
                {
                    continue;
                }

                // we should throw if the property type on the client does not match with the property type in the server
                // This is a breaking change from V1/V2 where we allowed materialization of entities into non-entities and vice versa
                if (ClientTypeUtil.TypeOrElementTypeIsEntity(property.PropertyType))
                {
                    throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidEntityType(property.EntityCollectionItemType ?? property.PropertyType));
                }

                if (property.IsKnownType)
                {
                    // Note: MaterializeDataValue materializes only properties of primitive types. Materialization specific
                    // to complex types and collections is done later.
                    this.MaterializePrimitiveDataValue(property.NullablePropertyType, odataProperty);
                }
            }
        }
Пример #4
0
 internal override NewExpression VisitNew(NewExpression nex)
 {
     if (ResourceBinder.PatternRules.MatchNewDataServiceCollectionOfT(nex))
     {
         if (ClientTypeUtil.TypeOrElementTypeIsEntity(nex.Type))
         {
             foreach (Expression expression in nex.Arguments)
             {
                 if (expression.NodeType != ExpressionType.Constant)
                 {
                     base.Visit(expression);
                 }
             }
             return(nex);
         }
     }
     else if (ResourceBinder.PatternRules.MatchNewCollectionOfT(nex) && !ClientTypeUtil.TypeOrElementTypeIsEntity(nex.Type))
     {
         foreach (Expression expression2 in nex.Arguments)
         {
             if (expression2.NodeType != ExpressionType.Constant)
             {
                 base.Visit(expression2);
             }
         }
         return(nex);
     }
     throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjectionToEntity(this.type, nex.ToString()));
 }
Пример #5
0
        /// <summary>
        /// Appends the given property and source TypeAs to the projection and expand paths.
        /// </summary>
        /// <param name="pi">Navigation property</param>
        /// <param name="convertedSourceType">The TypeAs type if the source of the member access expression is a TypeAs operation. Null otherwise.</param>
        /// <param name="context">Data service context instance.</param>
        internal void AppendPropertyToPath(PropertyInfo pi, Type convertedSourceType, DataServiceContext context)
        {
            Debug.Assert(pi != null, "pi != null");

            StringBuilder sb;
            bool          propertyTypeisEntityType = ClientTypeUtil.TypeOrElementTypeIsEntity(pi.PropertyType);

            string convertedSourceTypeName = (convertedSourceType == null) ? null : UriHelper.GetEntityTypeNameForUriAndValidateMaxProtocolVersion(convertedSourceType, context, ref this.uriVersion);

            if (propertyTypeisEntityType)
            {
                // an entity, so need to append to expand path also
                if (convertedSourceType != null)
                {
                    AppendToExpandPath(convertedSourceTypeName);
                }

                AppendToExpandPath(pi.Name);
            }

            sb = null;
            if (convertedSourceType != null)
            {
                AppendToProjectionPath(convertedSourceTypeName, false);
            }

            sb = AppendToProjectionPath(pi.Name, false);
            if (propertyTypeisEntityType)
            {
                AddEntireEntityMarker(sb);
            }
        }
Пример #6
0
        /// <summary>
        /// CODE: x
        /// ORIGINAL: Convert(x, t) where t is assignable from typeof(x)
        /// ORIGINAL: x as t, where t is assignable from typeof(x)
        /// ORIGINAL: and typeof(x) or t are not known primitives unless typeof(x) == t
        /// ORIGINAL: and x is not a collection of entity types
        /// NORMALIZED: x
        /// </summary>
        internal override Expression VisitUnary(UnaryExpression u)
        {
            UnaryExpression visited = (UnaryExpression)base.VisitUnary(u);
            Expression      result  = visited;

            // Note that typically we would record a potential rewrite
            // after extracting the conversion, but we avoid doing this
            // because it breaks undoing the rewrite by making the non-local
            // change circular, ie:
            //   unary [operand = a]
            // becomes
            //   a <- unary [operand = a]
            // So the undoing visits a, then the original unary, then the
            // operand and again the unary, the operand, etc.
            this.RecordRewrite(u, result);

            // Convert(x, t) or x as t, where t is assignable from typeof(x)
            if ((visited.NodeType == ExpressionType.Convert || visited.NodeType == ExpressionType.TypeAs) && visited.Type.IsAssignableFrom(visited.Operand.Type))
            {
                // typeof(x) or t are not known primitives unless typeof(x) == t
                if (!PrimitiveType.IsKnownNullableType(visited.Operand.Type) && !PrimitiveType.IsKnownNullableType(visited.Type) || visited.Operand.Type == visited.Type)
                {
                    // x is not a collection of entity types
                    if (!(ClientTypeUtil.TypeOrElementTypeIsEntity(visited.Operand.Type) && ProjectionAnalyzer.IsCollectionProducingExpression(visited.Operand)))
                    {
                        result = visited.Operand;
                    }
                }
            }

            return(result);
        }
Пример #7
0
 internal override Expression VisitLambda(LambdaExpression lambda)
 {
     if (!this.topLevelProjectionFound || ((lambda.Parameters.Count == 1) && ClientTypeUtil.TypeOrElementTypeIsEntity(lambda.Parameters[0].Type)))
     {
         this.topLevelProjectionFound = true;
         ParameterExpression expectedType = Expression.Parameter(typeof(Type), "type" + this.identifierId);
         ParameterExpression entry        = Expression.Parameter(typeof(object), "entry" + this.identifierId);
         this.identifierId++;
         this.pathBuilder.EnterLambdaScope(lambda, entry, expectedType);
         ProjectionPath        startPath = new ProjectionPath(lambda.Parameters[0], expectedType, entry);
         ProjectionPathSegment item      = new ProjectionPathSegment(startPath, null, null);
         startPath.Add(item);
         ExpressionAnnotation annotation = new ExpressionAnnotation {
             Segment = item
         };
         this.annotations[lambda.Parameters[0]] = annotation;
         Expression expression4 = this.Visit(lambda.Body);
         if (expression4.Type.IsValueType)
         {
             expression4 = Expression.Convert(expression4, typeof(object));
         }
         Expression expression = Expression.Lambda <Func <object, object, Type, object> >(expression4, new ParameterExpression[] { this.materializerExpression, entry, expectedType });
         this.pathBuilder.LeaveLambdaScope();
         return(expression);
     }
     return(base.VisitLambda(lambda));
 }
Пример #8
0
        internal override Expression VisitConditional(ConditionalExpression conditional)
        {
            Expression expressionBeforeNormalization = this.GetExpressionBeforeNormalization(conditional);

            if (expressionBeforeNormalization != conditional)
            {
                return(this.Visit(expressionBeforeNormalization));
            }
            ResourceBinder.PatternRules.MatchNullCheckResult nullCheck = ResourceBinder.PatternRules.MatchNullCheck(this.pathBuilder.LambdaParameterInScope, conditional);
            if (!nullCheck.Match || !ClientTypeUtil.TypeOrElementTypeIsEntity(ResourceBinder.StripConvertToAssignable(nullCheck.TestToNullExpression).Type))
            {
                Expression test = null;
                if (nullCheck.Match)
                {
                    Expression left = this.Visit(nullCheck.TestToNullExpression);
                    if (left.NodeType == ExpressionType.Convert)
                    {
                        left = ((UnaryExpression)left).Operand;
                    }
                    test = Expression.MakeBinary(ExpressionType.Equal, left, Expression.Constant(null));
                }
                if (test == null)
                {
                    test = this.Visit(conditional.Test);
                }
                Expression ifTrue  = this.Visit(conditional.IfTrue);
                Expression ifFalse = this.Visit(conditional.IfFalse);
                if (((test != conditional.Test) || (ifTrue != conditional.IfTrue)) || (ifFalse != conditional.IfFalse))
                {
                    return(Expression.Condition(test, ifTrue, ifFalse, ifTrue.Type.IsAssignableFrom(ifFalse.Type) ? ifTrue.Type : ifFalse.Type));
                }
            }
            return(this.RebindConditionalNullCheck(conditional, nullCheck));
        }
Пример #9
0
        private Expression RebindMethodCallForMemberSelect(MethodCallExpression call)
        {
            Expression           key = null;
            ExpressionAnnotation annotation;
            Expression           expression2 = this.Visit(call.Arguments[0]);

            this.annotations.TryGetValue(expression2, out annotation);
            if (annotation != null)
            {
                LambdaExpression    expression3 = call.Arguments[1] as LambdaExpression;
                ParameterExpression expression4 = expression3.Parameters.Last <ParameterExpression>();
                Expression          expression5 = this.Visit(call.Arguments[1]);
                if (ClientTypeUtil.TypeOrElementTypeIsEntity(expression4.Type))
                {
                    Type type = call.Method.ReturnType.GetGenericArguments()[0];
                    key = CallMaterializer("ProjectionSelect", new Expression[] { this.materializerExpression, this.pathBuilder.ParameterEntryInScope, this.pathBuilder.ExpectedParamTypeInScope, Expression.Constant(type, typeof(Type)), Expression.Constant(annotation.Segment.StartPath, typeof(object)), expression5 });
                    this.annotations.Add(key, annotation);
                    key = CallMaterializerWithType("EnumerateAsElementType", new Type[] { type }, new Expression[] { key });
                    this.annotations.Add(key, annotation);
                }
                else
                {
                    key = Expression.Call(call.Method, expression2, expression5);
                    this.annotations.Add(key, annotation);
                }
            }
            if (key == null)
            {
                key = base.VisitMethodCall(call);
            }
            return(key);
        }
Пример #10
0
        internal void AppendPropertyToPath(PropertyInfo pi, Type convertedSourceType, DataServiceContext context)
        {
            bool   flag = ClientTypeUtil.TypeOrElementTypeIsEntity(pi.PropertyType);
            string name = (convertedSourceType == null) ? null : System.Data.Services.Client.UriHelper.GetEntityTypeNameForUriAndValidateMaxProtocolVersion(convertedSourceType, context, ref this.uriVersion);

            if (flag)
            {
                if (convertedSourceType != null)
                {
                    this.AppendToExpandPath(name);
                }
                this.AppendToExpandPath(pi.Name);
            }
            StringBuilder sb = null;

            if (convertedSourceType != null)
            {
                this.AppendToProjectionPath(name, false);
            }
            sb = this.AppendToProjectionPath(pi.Name, false);
            if (flag)
            {
                AddEntireEntityMarker(sb);
            }
        }
            internal override Expression VisitMemberAccess(MemberExpression m)
            {
                Debug.Assert(m != null, "m != null");

                this.leafExpressionIsMemberAccess = true;

                // Only allowed to project entities
                if (!ClientTypeUtil.TypeOrElementTypeIsEntity(m.Expression.Type) ||
                    IsCollectionProducingExpression(m.Expression))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjectionToEntity(this.type, m.ToString()));
                }

                PropertyInfo pi;
                Expression   boundTarget;

                if (ResourceBinder.PatternRules.MatchNonPrivateReadableProperty(m, out pi, out boundTarget))
                {
                    Expression e = base.VisitMemberAccess(m);
                    Type       convertedType;
                    ResourceBinder.StripTo <Expression>(m.Expression, out convertedType);
                    this.builder.AppendPropertyToPath(pi, convertedType, this.context);

                    this.leafExpressionIsMemberAccess = false;
                    return(e);
                }

                throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjectionToEntity(this.type, m.ToString()));
            }
Пример #12
0
        /// <summary>
        /// Determine if the specified type is an DataServiceCollection.
        /// </summary>
        /// <remarks>
        /// If there a generic class in the inheritance hierarchy of the type, that has a single
        /// entity type paramenter T, and is assignable to DataServiceCollection(Of T), then
        /// the type is an DataServiceCollection.
        /// </remarks>
        /// <param name="collectionType">An object type specifier.</param>
        /// <param name="model">The client model.</param>
        /// <returns>true if the type is an DataServiceCollection; otherwise false.</returns>
        internal static bool IsDataServiceCollection(Type collectionType, ClientEdmModel model)
        {
            Debug.Assert(collectionType != null, "Argument 'collectionType' cannot be null.");

            metadataCacheLock.EnterReadLock();
            try
            {
                object resultAsObject;
                if (knownObservableCollectionTypes.TryGetValue(collectionType, out resultAsObject))
                {
                    return(resultAsObject == TrueObject);
                }
            }
            finally
            {
                metadataCacheLock.ExitReadLock();
            }

            Type type   = collectionType;
            bool result = false;

            while (type != null)
            {
                if (type.IsGenericType())
                {
                    // Is there a generic class in the inheritance hierarchy, that has a single
                    // entity type paramenter T, and is assignable to DataServiceCollection<T>
                    Type[] parms = type.GetGenericArguments();

                    if (parms != null && parms.Length == 1 && ClientTypeUtil.TypeOrElementTypeIsEntity(parms[0]))
                    {
                        // if ObservableCollection is not available dataServiceCollection will be null
                        Type dataServiceCollection = WebUtil.GetDataServiceCollectionOfT(parms);
                        if (dataServiceCollection != null && dataServiceCollection.IsAssignableFrom(type))
                        {
                            result = true;
                            break;
                        }
                    }
                }

                type = type.GetBaseType();
            }

            metadataCacheLock.EnterWriteLock();
            try
            {
                if (!knownObservableCollectionTypes.ContainsKey(collectionType))
                {
                    knownObservableCollectionTypes[collectionType] = result ? TrueObject : FalseObject;
                }
            }
            finally
            {
                metadataCacheLock.ExitWriteLock();
            }

            return(result);
        }
Пример #13
0
 internal override Expression VisitTypeIs(TypeBinaryExpression b)
 {
     if (ClientTypeUtil.TypeOrElementTypeIsEntity(b.Expression.Type) || ProjectionAnalyzer.IsCollectionProducingExpression(b.Expression))
     {
         throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjection(this.type, b.ToString()));
     }
     return(base.VisitTypeIs(b));
 }
Пример #14
0
 internal override Expression VisitConstant(ConstantExpression c)
 {
     if (ClientTypeUtil.TypeOrElementTypeIsEntity(c.Type))
     {
         throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjection(this.type, c.ToString()));
     }
     return(base.VisitConstant(c));
 }
Пример #15
0
 internal override NewExpression VisitNew(NewExpression nex)
 {
     if (ClientTypeUtil.TypeOrElementTypeIsEntity(nex.Type) && !ResourceBinder.PatternRules.MatchNewDataServiceCollectionOfT(nex))
     {
         throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjection(this.type, nex.ToString()));
     }
     return(base.VisitNew(nex));
 }
Пример #16
0
 internal override Expression VisitMemberInit(MemberInitExpression init)
 {
     if (!ClientTypeUtil.TypeOrElementTypeIsEntity(init.Type))
     {
         throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjectionToEntity(this.type, init.ToString()));
     }
     ProjectionAnalyzer.Analyze(init, this.box, this.context);
     return(init);
 }
Пример #17
0
        public void IFTypeProperty_HasKeyAttribute_TypeIsEntity()
        {
            //Arrange
            Type person = typeof(Person);
            //Act
            bool actualResult = ClientTypeUtil.TypeOrElementTypeIsEntity(person);

            //Assert
            Assert.True(actualResult);
        }
Пример #18
0
        public void IFTypeProperty_HasNoKeyAttribute_TypeIsNotEntity()
        {
            //Arrange
            Type student = typeof(Student);
            //Act
            bool actualResult = ClientTypeUtil.TypeOrElementTypeIsEntity(student);

            //Assert
            Assert.False(actualResult);
        }
Пример #19
0
        public void IFTypeProperty_HasKeyAttributeAndOneProperty_TypeIsEntityAndDoesNotThrowException()
        {
            //Arrange
            Type car = typeof(Car);

            //Act
            bool actualResult = ClientTypeUtil.TypeOrElementTypeIsEntity(car);

            //Assert
            Assert.True(actualResult);
        }
            internal override Expression VisitBinary(BinaryExpression b)
            {
                if (ClientTypeUtil.TypeOrElementTypeIsEntity(b.Left.Type) ||
                    ClientTypeUtil.TypeOrElementTypeIsEntity(b.Right.Type) ||
                    IsCollectionProducingExpression(b.Left) || IsCollectionProducingExpression(b.Right))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, b.ToString()));
                }

                return(base.VisitBinary(b));
            }
            internal override Expression VisitInvocation(InvocationExpression iv)
            {
                if (ClientTypeUtil.TypeOrElementTypeIsEntity(iv.Expression.Type) ||
                    IsCollectionProducingExpression(iv.Expression) ||
                    iv.Arguments.Any(a => ClientTypeUtil.TypeOrElementTypeIsEntity(a.Type) || IsCollectionProducingExpression(a)))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, iv.ToString()));
                }

                return(base.VisitInvocation(iv));
            }
            internal override Expression VisitMemberInit(MemberInitExpression init)
            {
                if (!ClientTypeUtil.TypeOrElementTypeIsEntity(init.Type))
                {
                    // MemberInit to a complex type is not supported on entity types.
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjectionToEntity(this.type, init.ToString()));
                }

                ProjectionAnalyzer.Analyze(init, this.builder, this.context);
                return(init);
            }
Пример #23
0
 private static void Analyze(MemberInitExpression mie, PathBox pb, DataServiceContext context)
 {
     if (ClientTypeUtil.TypeOrElementTypeIsEntity(mie.Type))
     {
         EntityProjectionAnalyzer.Analyze(mie, pb, context);
     }
     else
     {
         NonEntityProjectionAnalyzer.Analyze(mie, pb, context);
     }
 }
            internal override NewExpression VisitNew(NewExpression nex)
            {
                // Allow creation of DataServiceCollection<T> objects in projections, stop others that project entities
                if (ClientTypeUtil.TypeOrElementTypeIsEntity(nex.Type) &&
                    !ResourceBinder.PatternRules.MatchNewDataServiceCollectionOfT(nex))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, nex.ToString()));
                }

                return(base.VisitNew(nex));
            }
Пример #25
0
 internal override Expression VisitParameter(ParameterExpression p)
 {
     if (ClientTypeUtil.TypeOrElementTypeIsEntity(p.Type))
     {
         if (p != this.box.ParamExpressionInScope)
         {
             throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjection(this.type, p.ToString()));
         }
         this.box.StartNewPath();
     }
     return(p);
 }
Пример #26
0
        internal void EnterLambdaScope(LambdaExpression lambda, Expression entry, Expression expectedType)
        {
            ParameterExpression item = lambda.Parameters[0];
            Type type = lambda.Body.Type;
            bool flag = ClientTypeUtil.TypeOrElementTypeIsEntity(type);

            this.entityInScope.Push(flag);
            this.parameterExpressions.Push(item);
            this.parameterExpressionTypes.Push(expectedType);
            this.parameterEntries.Push(entry);
            this.parameterProjectionTypes.Push(type);
        }
Пример #27
0
 internal static string GetEntityTypeNameForUriAndValidateMaxProtocolVersion(Type type, DataServiceContext context, ref Version uriVersion)
 {
     if (context.MaxProtocolVersionAsVersion < Util.DataServiceVersion3)
     {
         throw new NotSupportedException(Strings.ALinq_TypeAsNotSupportedForMaxDataServiceVersionLessThan3);
     }
     if (!ClientTypeUtil.TypeOrElementTypeIsEntity(type))
     {
         throw new NotSupportedException(Strings.ALinq_TypeAsArgumentNotEntityType(type.FullName));
     }
     WebUtil.RaiseVersion(ref uriVersion, Util.DataServiceVersion3);
     return(context.ResolveNameFromType(type) ?? type.FullName);
 }
Пример #28
0
        /// <summary>
        /// Determine if the specified type is an entity type.
        /// </summary>
        /// <param name="type">An object type specifier.</param>
        /// <param name="model">The client model.</param>
        /// <returns>true if the type is an entity type; otherwise false.</returns>
        internal static bool IsEntityType(Type type, ClientEdmModel model)
        {
            Debug.Assert(type != null, "Argument 'type' cannot be null.");

            metadataCacheLock.EnterReadLock();
            try
            {
                if (knownNonEntityTypes.Contains(type))
                {
                    return(false);
                }
            }
            finally
            {
                metadataCacheLock.ExitReadLock();
            }

            bool isEntityType;

            try
            {
                if (BindingEntityInfo.IsDataServiceCollection(type, model))
                {
                    return(false);
                }

                isEntityType = ClientTypeUtil.TypeOrElementTypeIsEntity(type);
            }
            catch (InvalidOperationException)
            {
                isEntityType = false;
            }

            if (!isEntityType)
            {
                metadataCacheLock.EnterWriteLock();
                try
                {
                    if (!knownNonEntityTypes.Contains(type))
                    {
                        knownNonEntityTypes.Add(type);
                    }
                }
                finally
                {
                    metadataCacheLock.ExitWriteLock();
                }
            }

            return(isEntityType);
        }
Пример #29
0
 internal override Expression VisitConditional(ConditionalExpression c)
 {
     ResourceBinder.PatternRules.MatchNullCheckResult result = ResourceBinder.PatternRules.MatchNullCheck(this.box.ParamExpressionInScope, c);
     if (result.Match)
     {
         this.Visit(result.AssignExpression);
         return(c);
     }
     if (((ClientTypeUtil.TypeOrElementTypeIsEntity(c.Test.Type) || ClientTypeUtil.TypeOrElementTypeIsEntity(c.IfTrue.Type)) || (ClientTypeUtil.TypeOrElementTypeIsEntity(c.IfFalse.Type) || ProjectionAnalyzer.IsCollectionProducingExpression(c.Test))) || (ProjectionAnalyzer.IsCollectionProducingExpression(c.IfTrue) || ProjectionAnalyzer.IsCollectionProducingExpression(c.IfFalse)))
     {
         throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjection(this.type, c.ToString()));
     }
     return(base.VisitConditional(c));
 }
Пример #30
0
 internal override Expression VisitInvocation(InvocationExpression iv)
 {
     if ((ClientTypeUtil.TypeOrElementTypeIsEntity(iv.Expression.Type) || ProjectionAnalyzer.IsCollectionProducingExpression(iv.Expression)) || iv.Arguments.Any <Expression>(delegate(Expression a) {
         if (!ClientTypeUtil.TypeOrElementTypeIsEntity(a.Type))
         {
             return(ProjectionAnalyzer.IsCollectionProducingExpression(a));
         }
         return(true);
     }))
     {
         throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjection(this.type, iv.ToString()));
     }
     return(base.VisitInvocation(iv));
 }