/// <summary>
        /// Constructor taking a metadata context, an structural type, and a parent custom type descriptor
        /// </summary>
        /// <param name="typeDescriptionContext">The <see cref="LinqToEntitiesTypeDescriptionContext"/> context.</param>
        /// <param name="edmType">The <see cref="StructuralType"/> type (can be an entity or complex type).</param>
        /// <param name="parent">The parent custom type descriptor.</param>
        public LinqToEntitiesTypeDescriptor(LinqToEntitiesTypeDescriptionContext typeDescriptionContext, StructuralType edmType, ICustomTypeDescriptor parent)
            : base(parent)
        {
            _typeDescriptionContext = typeDescriptionContext;
            _edmType = edmType;

            EdmMember[] timestampMembers = _edmType.Members.Where(p => ObjectContextUtilities.IsConcurrencyTimestamp(p)).ToArray();
            if (timestampMembers.Length == 1)
            {
                _timestampMember = timestampMembers[0];
            }

            if (edmType.BuiltInTypeKind == BuiltInTypeKind.EntityType)
            {
                // if any FK member of any association is also part of the primary key, then the key cannot be marked
                // Editable(false)
                EntityType entityType = (EntityType)edmType;
                _foreignKeyMembers = new HashSet<EdmMember>(entityType.NavigationProperties.SelectMany(p => p.GetDependentProperties()));
                foreach (EdmProperty foreignKeyMember in _foreignKeyMembers)
                {
                    if (entityType.KeyMembers.Contains(foreignKeyMember))
                    {
                        _keyIsEditable = true;
                        break;
                    }
                }
            }
        }
        // effects: try to find setter expression for the given member
        // requires: command tree must be an insert or update tree (since other DML trees hnabve 
        private static bool TryGetSetterExpression(
            DbModificationCommandTree tree, EdmMember member, ModificationOperator op, out DbSetClause setter)
        {
            Debug.Assert(op == ModificationOperator.Insert || op == ModificationOperator.Update, "only inserts and updates have setters");
            IEnumerable<DbModificationClause> clauses;
            if (ModificationOperator.Insert == op)
            {
                clauses = ((DbInsertCommandTree)tree).SetClauses;
            }
            else
            {
                clauses = ((DbUpdateCommandTree)tree).SetClauses;
            }
            foreach (DbSetClause setClause in clauses)
            {
                // check if this is the correct setter
                if (((DbPropertyExpression)setClause.Property).Property.EdmEquals(member))
                {
                    setter = setClause;
                    return true;
                }
            }

            // no match found
            setter = null;
            return false;
        }
예제 #3
0
 // <summary>
 // Given the type in the target space and the member name in the source space,
 // get the corresponding member in the target space
 // For e.g.  consider a Conceptual Type 'Abc' with a member 'Def' and a CLR type
 // 'XAbc' with a member 'YDef'. If one has a reference to Abc one can
 // invoke GetMember(Abc,"YDef") to retrieve the member metadata for Def
 // </summary>
 // <param name="type"> The type in the target perspective </param>
 // <param name="memberName"> the name of the member in the source perspective </param>
 // <param name="ignoreCase"> Whether to do case-sensitive member look up or not </param>
 // <param name="outMember"> returns the member in target space, if a match is found </param>
 internal virtual bool TryGetMember(StructuralType type, String memberName, bool ignoreCase, out EdmMember outMember)
 {
     DebugCheck.NotNull(type);
     Check.NotEmpty(memberName, "memberName");
     outMember = null;
     return type.Members.TryGetValue(memberName, ignoreCase, out outMember);
 }
 internal ExplicitDiscriminatorMap(DiscriminatorMap template)
 {
     m_typeMap = template.TypeMap;
     m_discriminatorProperty = template.Discriminator.Property;
     m_properties = new ReadOnlyCollection<EdmProperty>(template.PropertyMap.Select(propertyValuePair => propertyValuePair.Key)
                            .ToList());
 }
 internal ExplicitDiscriminatorMap(DiscriminatorMap template)
 {
     m_typeMap = template.TypeMap;
     m_discriminatorProperty = template.Discriminator.Property;
     m_properties = template.PropertyMap.Select(propertyValuePair => propertyValuePair.Key)
         .ToList().AsReadOnly();
 }
        internal EntityProxyMemberInfo(EdmMember member, int propertyIndex)
        {
            Debug.Assert(member != null, "member must be non-null");
            Debug.Assert(propertyIndex > -1, "propertyIndex must be non-negative");

            _member = member;
            _propertyIndex = propertyIndex;
        }
        internal EntityProxyMemberInfo(EdmMember member, int propertyIndex)
        {
            DebugCheck.NotNull(member);
            Debug.Assert(propertyIndex > -1, "propertyIndex must be non-negative");

            _member = member;
            _propertyIndex = propertyIndex;
        }
예제 #8
0
        /// <summary>
        /// Initializes a new <see cref="T:System.Data.Entity.Core.Common.FieldMetadata" /> object with the specified ordinal value and field type.
        /// </summary>
        /// <param name="ordinal">An integer specified the location of the metadata.</param>
        /// <param name="fieldType">The field type.</param>
        public FieldMetadata(int ordinal, EdmMember fieldType)
        {
            if (ordinal < 0)
            {
                throw new ArgumentOutOfRangeException("ordinal");
            }
            Check.NotNull(fieldType, "fieldType");

            _fieldType = fieldType;
            _ordinal = ordinal;
        }
예제 #9
0
        /// <summary>
        ///     Used to construct a field metadata object relating a column ordinal and an ImemberMetadata.
        /// </summary>
        /// <param name="ordinal"> Column oridnal </param>
        /// <param name="fieldType"> Metadata member </param>
        public FieldMetadata(int ordinal, EdmMember fieldType)
        {
            if (ordinal < 0)
            {
                throw new ArgumentOutOfRangeException("ordinal");
            }
            if (null == fieldType)
            {
                throw new ArgumentNullException("fieldType");
            }

            _fieldType = fieldType;
            _ordinal = ordinal;
        }
        /// <summary>
        ///     Given the type in the target space and the member name in the source space,
        ///     get the corresponding member in the target space
        ///     For e.g.  consider a Conceptual Type Foo with a member bar and a CLR type
        ///     XFoo with a member YBar. If one has a reference to Foo one can
        ///     invoke GetMember(Foo,"YBar") to retrieve the member metadata for bar
        /// </summary>
        /// <param name="type"> The type in the target perspective </param>
        /// <param name="memberName"> the name of the member in the source perspective </param>
        /// <param name="ignoreCase"> true for case-insensitive lookup </param>
        /// <param name="outMember"> returns the edmMember if a match is found </param>
        /// <returns> true if a match is found, otherwise false </returns>
        internal override bool TryGetMember(StructuralType type, String memberName, bool ignoreCase, out EdmMember outMember)
        {
            outMember = null;
            Map map = null;

            if (MetadataWorkspace.TryGetMap(type, DataSpace.OCSpace, out map))
            {
                var objectTypeMap = map as ObjectTypeMapping;

                if (objectTypeMap != null)
                {
                    var objPropertyMapping = objectTypeMap.GetMemberMapForClrMember(memberName, ignoreCase);
                    if (null != objPropertyMapping)
                    {
                        outMember = objPropertyMapping.EdmMember;
                        return true;
                    }
                }
            }
            return false;
        }
        // <summary>
        // Add an entry that the given property of the given var is a computation represented
        // by the computationTemplate over the var represented by the given groupAggregateVarInfo
        // </summary>
        internal void Add(
            Var var, GroupAggregateVarInfo groupAggregateVarInfo, Node computationTemplate, bool isUnnested, EdmMember property)
        {
            if (property == null)
            {
                Add(var, groupAggregateVarInfo, computationTemplate, isUnnested);
                return;
            }
            if (_groupAggregateVarRelatedVarPropertyToInfo == null)
            {
                _groupAggregateVarRelatedVarPropertyToInfo = new Dictionary<Var, Dictionary<EdmMember, GroupAggregateVarRefInfo>>();
            }
            Dictionary<EdmMember, GroupAggregateVarRefInfo> varPropertyDictionary;
            if (!_groupAggregateVarRelatedVarPropertyToInfo.TryGetValue(var, out varPropertyDictionary))
            {
                varPropertyDictionary = new Dictionary<EdmMember, GroupAggregateVarRefInfo>();
                _groupAggregateVarRelatedVarPropertyToInfo.Add(var, varPropertyDictionary);
            }
            varPropertyDictionary.Add(property, new GroupAggregateVarRefInfo(groupAggregateVarInfo, computationTemplate, isUnnested));

            // Note: The following line is not necessary with the current usage pattern, this method is 
            // never called with a new groupAggregateVarInfo thus it is a no-op.
            _groupAggregateVarInfos.Add(groupAggregateVarInfo);
        }
예제 #12
0
        private RecordColumnMap CreateRecordColumnMap(TypeInfo typeInfo, string name)
        {
            PlanCompiler.Assert(typeInfo.Type.EdmType is md.RowType, "not RowType");
            SimpleColumnMap nullSentinelColumnMap = null;

            if (typeInfo.HasNullSentinelProperty)
            {
                nullSentinelColumnMap = CreateSimpleColumnMap(
                    md.Helper.GetModelTypeUsage(typeInfo.NullSentinelProperty), c_NullSentinelColumnName);
            }

            var properties            = TypeHelpers.GetProperties(typeInfo.Type);
            var propertyColumnMapList = new ColumnMap[properties.Count];

            for (var i = 0; i < propertyColumnMapList.Length; ++i)
            {
                md.EdmMember property = properties[i];
                propertyColumnMapList[i] = CreateColumnMap(md.Helper.GetModelTypeUsage(property), property.Name);
            }

            var result = new RecordColumnMap(typeInfo.Type, name, propertyColumnMapList, nullSentinelColumnMap);

            return(result);
        }
예제 #13
0
파일: EpmHelper.cs 프로젝트: nickchal/pash
 internal static IEnumerable<EpmPropertyInformation> GetEpmInformationFromProperty(EdmMember edmMember)
 {
     return GetEpmPropertyInformation(edmMember, edmMember.DeclaringType.Name, edmMember.Name);
 }
 public bool CanProxyMember(EdmMember member)
 {
     return _members.Contains(member);
 }
        /// <summary>
        ///     Construct an interception delegate for the specified proxy member.
        /// </summary>
        /// <param name="member"> EdmMember that specifies the member to be intercepted. </param>
        /// <param name="proxyType"> Type of the proxy. </param>
        /// <param name="lazyLoadBehavior"> LazyLoadBehavior object that supplies the behavior to load related ends. </param>
        private static void InterceptMember(EdmMember member, Type proxyType, EntityProxyTypeInfo proxyTypeInfo)
        {
            var property = EntityUtil.GetTopProperty(proxyType, member.Name);
            Debug.Assert(
                property != null,
                String.Format(
                    CultureInfo.CurrentCulture, "Expected property {0} to be defined on proxy type {1}", member.Name, proxyType.FullName));

            var interceptorField = proxyType.GetField(
                LazyLoadImplementor.GetInterceptorFieldName(member.Name),
                BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.NonPublic);
            Debug.Assert(
                interceptorField != null,
                String.Format(
                    CultureInfo.CurrentCulture, "Expected interceptor field for property {0} to be defined on proxy type {1}", member.Name,
                    proxyType.FullName));

            var interceptorDelegate =
                typeof(LazyLoadBehavior).GetMethod("GetInterceptorDelegate", BindingFlags.NonPublic | BindingFlags.Static).
                                         MakeGenericMethod(proxyType, property.PropertyType).
                                         Invoke(null, new object[] { member, proxyTypeInfo.EntityWrapperDelegate }) as Delegate;

            AssignInterceptionDelegate(interceptorDelegate, interceptorField);
        }
예제 #16
0
 /// <summary>Adds a member to this type</summary>
 /// <param name="member"> The member to add </param>
 public void AddMember(EdmMember member)
 {
     this.AddMember(member, false);
 }
예제 #17
0
 private static int FindPosition(EdmType type, EdmMember member)
 {
     var pos = 0;
     foreach (EdmMember m in TypeHelpers.GetAllStructuralMembers(type))
     {
         if (m.EdmEquals(member))
         {
             return pos;
         }
         pos++;
     }
     PlanCompiler.Assert(false, "Could not find property " + member + " in type " + type.Name);
     return -1;
 }
예제 #18
0
 private static bool NonPrimitiveMemberMatchesByConvention(PropertyInfo clrProperty, EdmMember cspaceMember)
 {
     return !clrProperty.PropertyType.IsValueType() && !clrProperty.PropertyType.IsAssignableFrom(typeof(string))
            && clrProperty.Name == cspaceMember.Name;
 }
예제 #19
0
 /// <summary>Removes a member from this type.</summary>
 /// <param name="member">The member to remove.</param>
 public virtual void RemoveMember(EdmMember member)
 {
     Check.NotNull <EdmMember>(member, nameof(member));
     Util.ThrowIfReadOnly((MetadataItem)this);
     this._members.Remove(member);
 }
예제 #20
0
 internal virtual void NotifyItemIdentityChanged(EdmMember item, string initialIdentity)
 {
     this._members.HandleIdentityChange(item, initialIdentity);
 }
        // <summary>
        // Load all the property metadata of the given type
        // </summary>
        // <param name="structuralType"> The type where properties are loaded </param>
        private void LoadPropertiesFromType(StructuralType structuralType)
        {
            // Look at both public, internal, and private instanced properties declared at this type, inherited members
            // are not looked at.  Internal and private properties are also looked at because they are also schematized fields
            var properties = structuralType.ClrType.GetDeclaredProperties().Where(p => !p.IsStatic());

            foreach (var property in properties)
            {
                EdmMember newMember           = null;
                var       isEntityKeyProperty = false; //used for EdmScalarProperties only

                // EdmScalarPropertyAttribute, EdmComplexPropertyAttribute and EdmRelationshipNavigationPropertyAttribute
                // are all EdmPropertyAttributes that we need to process. If the current property is not an EdmPropertyAttribute
                // we will just ignore it and skip to the next property.
                if (property.GetCustomAttributes <EdmRelationshipNavigationPropertyAttribute>(inherit: false).Any())
                {
                    // keep the loop var from being lifted
                    var pi = property;
                    _unresolvedNavigationProperties.Add(
                        () =>
                        ResolveNavigationProperty(structuralType, pi));
                }
                else if (property.GetCustomAttributes <EdmScalarPropertyAttribute>(inherit: false).Any())
                {
                    if ((Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType).IsEnum())
                    {
                        TrackClosure(property.PropertyType);
                        var local = property;
                        AddTypeResolver(() => ResolveEnumTypeProperty(structuralType, local));
                    }
                    else
                    {
                        newMember = LoadScalarProperty(structuralType.ClrType, property, out isEntityKeyProperty);
                    }
                }
                else if (property.GetCustomAttributes <EdmComplexPropertyAttribute>(inherit: false).Any())
                {
                    TrackClosure(property.PropertyType);
                    // keep loop var from being lifted
                    var local = property;
                    AddTypeResolver(() => ResolveComplexTypeProperty(structuralType, local));
                }

                if (newMember == null)
                {
                    // Property does not have one of the following attributes:
                    //     EdmScalarPropertyAttribute, EdmComplexPropertyAttribute, EdmRelationshipNavigationPropertyAttribute
                    // This means its an unmapped property and can be ignored.
                    // Or there were error encountered while loading the properties
                    continue;
                }

                // Add the property object to the type
                structuralType.AddMember(newMember);

                // Add to the entity's collection of key members
                // Do this here instead of in the if condition above for scalar properties because
                // we want to make sure the AddMember call above did not fail before updating the key members
                if (Helper.IsEntityType(structuralType) && isEntityKeyProperty)
                {
                    ((EntityType)structuralType).AddKeyMember(newMember);
                }
            }
        }
        internal void ResolveNavigationProperty(StructuralType declaringType, PropertyInfo propertyInfo)
        {
            // EdmScalarPropertyAttribute, EdmComplexPropertyAttribute and EdmRelationshipNavigationPropertyAttribute
            // are all EdmPropertyAttributes that we need to process. If the current property is not an EdmPropertyAttribute
            // we will just ignore it and skip to the next property.
            var relationshipPropertyAttributes = propertyInfo.GetCustomAttributes <EdmRelationshipNavigationPropertyAttribute>(inherit: false);

            Debug.Assert(relationshipPropertyAttributes.Count() == 1, "There should be exactly one property for every navigation property");

            // The only valid return types from navigation properties are:
            //     (1) EntityType
            //     (2) CollectionType containing valid EntityType

            // If TryGetLoadedType returned false, it could mean that we couldn't validate any part of the type, or it could mean that it's a generic
            // where the main generic type was validated, but the generic type parameter was not. We can't tell the difference, so just fail
            // with the same error message in both cases. The user will have to figure out which part of the type is wrong.
            // We can't just rely on checking for a generic because it can lead to a scenario where we report that the type parameter is invalid
            // when really it's the main generic type. That is more confusing than reporting the full name and letting the user determine the problem.
            EdmType propertyType;

            if (!TryGetLoadedType(propertyInfo.PropertyType, out propertyType)
                ||
                !(propertyType.BuiltInTypeKind == BuiltInTypeKind.EntityType ||
                  propertyType.BuiltInTypeKind == BuiltInTypeKind.CollectionType))
            {
                // Once an error is detected the property does not need to be validated further, just add to the errors
                // collection and continue with the next property. The failure will cause an exception to be thrown later during validation of all of the types.
                SessionData.EdmItemErrors.Add(
                    new EdmItemError(
                        Strings.Validator_OSpace_InvalidNavPropReturnType(
                            propertyInfo.Name, propertyInfo.DeclaringType.FullName, propertyInfo.PropertyType.FullName)));
                return;
            }
            // else we have a valid EntityType or CollectionType that contains EntityType. ResolveNonSchemaType enforces that a collection type
            // must contain an EntityType, and if it doesn't, propertyType will be null here. If propertyType is EntityType or CollectionType we know it is valid

            // Expecting EdmRelationshipNavigationPropertyAttribute to have AllowMultiple=False, so only look at first element in the attribute array

            var attribute = (EdmRelationshipNavigationPropertyAttribute)relationshipPropertyAttributes.First();

            EdmMember member = null;
            EdmType   type;

            if (SessionData.TypesInLoading.TryGetValue(attribute.RelationshipNamespaceName + "." + attribute.RelationshipName, out type)
                &&
                Helper.IsAssociationType(type))
            {
                var relationshipType = (AssociationType)type;
                if (relationshipType != null)
                {
                    // The return value of this property has been verified, so create the property now
                    var navigationProperty = new NavigationProperty(propertyInfo.Name, TypeUsage.Create(propertyType));
                    navigationProperty.RelationshipType = relationshipType;
                    member = navigationProperty;

                    if (relationshipType.Members[0].Name
                        == attribute.TargetRoleName)
                    {
                        navigationProperty.ToEndMember   = (RelationshipEndMember)relationshipType.Members[0];
                        navigationProperty.FromEndMember = (RelationshipEndMember)relationshipType.Members[1];
                    }
                    else if (relationshipType.Members[1].Name
                             == attribute.TargetRoleName)
                    {
                        navigationProperty.ToEndMember   = (RelationshipEndMember)relationshipType.Members[1];
                        navigationProperty.FromEndMember = (RelationshipEndMember)relationshipType.Members[0];
                    }
                    else
                    {
                        SessionData.EdmItemErrors.Add(
                            new EdmItemError(
                                Strings.TargetRoleNameInNavigationPropertyNotValid(
                                    propertyInfo.Name, propertyInfo.DeclaringType.FullName, attribute.TargetRoleName,
                                    attribute.RelationshipName)));
                        member = null;
                    }

                    if (member != null
                        &&
                        ((RefType)navigationProperty.FromEndMember.TypeUsage.EdmType).ElementType.ClrType != declaringType.ClrType)
                    {
                        SessionData.EdmItemErrors.Add(
                            new EdmItemError(
                                Strings.NavigationPropertyRelationshipEndTypeMismatch(
                                    declaringType.FullName,
                                    navigationProperty.Name,
                                    relationshipType.FullName,
                                    navigationProperty.FromEndMember.Name,
                                    ((RefType)navigationProperty.FromEndMember.TypeUsage.EdmType).ElementType.ClrType)));
                        member = null;
                    }
                }
            }
            else
            {
                SessionData.EdmItemErrors.Add(
                    new EdmItemError(
                        Strings.RelationshipNameInNavigationPropertyNotValid(
                            propertyInfo.Name, propertyInfo.DeclaringType.FullName, attribute.RelationshipName)));
            }

            if (member != null)
            {
                declaringType.AddMember(member);
            }
        }
예제 #23
0
 /// <summary>
 ///     Validates a EdmMember object to determine if it can be added to this type's
 ///     Members collection. If this method returns without throwing, it is assumed
 ///     the member is valid.
 /// </summary>
 /// <param name="member"> The member to validate </param>
 /// <exception cref="System.ArgumentException">Thrown if the member is not a EdmProperty</exception>
 internal override void ValidateMemberForAdd(EdmMember member)
 {
     Debug.Assert(
         Helper.IsEdmProperty(member),
         "Only members of type Property may be added to ComplexType.");
 }
예제 #24
0
        // <summary>
        // Given the type in the target space and the member name in the source space,
        // get the corresponding member in the target space
        // For e.g.  consider a Conceptual Type Abc with a member def and a CLR type
        // XAbc with a member YDef. If one has a reference to Abc one can
        // invoke GetMember(Abc,"YDef") to retrieve the member metadata for def
        // </summary>
        // <param name="type"> The type in the target perspective </param>
        // <param name="memberName"> the name of the member in the source perspective </param>
        // <param name="ignoreCase"> true for case-insensitive lookup </param>
        // <param name="outMember"> returns the edmMember if a match is found </param>
        // <returns> true if a match is found, otherwise false </returns>
        internal override bool TryGetMember(StructuralType type, String memberName, bool ignoreCase, out EdmMember outMember)
        {
            outMember = null;
            MappingBase map = null;

            if (MetadataWorkspace.TryGetMap(type, DataSpace.OCSpace, out map))
            {
                var objectTypeMap = map as ObjectTypeMapping;

                if (objectTypeMap != null)
                {
                    var objPropertyMapping = objectTypeMap.GetMemberMapForClrMember(memberName, ignoreCase);
                    if (null != objPropertyMapping)
                    {
                        outMember = objPropertyMapping.EdmMember;
                        return(true);
                    }
                }
            }
            return(false);
        }
예제 #25
0
 /// <summary>
 ///     Validates a EdmMember object to determine if it can be added to this type's
 ///     Members collection. If this method returns without throwing, it is assumed
 ///     the member is valid.
 /// </summary>
 /// <param name="member"> The member to validate </param>
 /// <exception cref="System.ArgumentException">Thrown if the member is not a EdmProperty</exception>
 internal override void ValidateMemberForAdd(EdmMember member)
 {
     Debug.Assert(
         Helper.IsEdmProperty(member) || Helper.IsNavigationProperty(member),
         "Only members of type Property may be added to Entity types.");
 }
예제 #26
0
 /// <summary>
 ///     Returns the slot index for the following member path: <paramref name="member" />.<paramref name="child" />, e.g., CPerson1.pid
 /// </summary>
 private int GetSlotIndex(MemberPath member, EdmMember child)
 {
     var fullMember = new MemberPath(member, child);
     var index = m_projectedSlotMap.IndexOf(fullMember);
     Debug.Assert(index != -1, "Couldn't locate " + fullMember + " in m_projectedSlotMap");
     return index;
 }
예제 #27
0
 internal static bool IsNavigationProperty(EdmMember member)
 {
     return(BuiltInTypeKind.NavigationProperty == member.BuiltInTypeKind);
 }
        private static void ValidateMembersMatch(EdmMember edmMember, EdmMember objectMember)
        {
            Debug.Assert(edmMember.DeclaringType.DataSpace == DataSpace.CSpace, "the cspace member is not on a cspace type");
            Debug.Assert(objectMember.DeclaringType.DataSpace == DataSpace.OSpace, "the ospace member is not on a cspace type");

            // Make sure the property type is the same
            if (edmMember.BuiltInTypeKind
                != objectMember.BuiltInTypeKind)
            {
                throw new MappingException(
                    Strings.Mapping_Default_OCMapping_MemberKind_Mismatch(
                        edmMember.Name, edmMember.DeclaringType.FullName, edmMember.BuiltInTypeKind,
                        objectMember.Name, objectMember.DeclaringType.FullName, objectMember.BuiltInTypeKind));
            }

            // Make sure the member type is the same
            if (edmMember.TypeUsage.EdmType.BuiltInTypeKind
                != objectMember.TypeUsage.EdmType.BuiltInTypeKind)
            {
                throw Error.Mapping_Default_OCMapping_Member_Type_Mismatch(
                    edmMember.TypeUsage.EdmType.Name, edmMember.TypeUsage.EdmType.BuiltInTypeKind, edmMember.Name,
                    edmMember.DeclaringType.FullName,
                    objectMember.TypeUsage.EdmType.Name, objectMember.TypeUsage.EdmType.BuiltInTypeKind, objectMember.Name,
                    objectMember.DeclaringType.FullName);
            }

            if (Helper.IsPrimitiveType(edmMember.TypeUsage.EdmType))
            {
                var memberType = Helper.GetSpatialNormalizedPrimitiveType(edmMember.TypeUsage.EdmType);

                // We expect the CLR prmitive type and their corresponding EDM primitive types to have the same primitive type kind (at least for now)
                if (memberType.PrimitiveTypeKind
                    != ((PrimitiveType)objectMember.TypeUsage.EdmType).PrimitiveTypeKind)
                {
                    throw new MappingException(
                        Strings.Mapping_Default_OCMapping_Invalid_MemberType(
                            edmMember.TypeUsage.EdmType.FullName, edmMember.Name, edmMember.DeclaringType.FullName,
                            objectMember.TypeUsage.EdmType.FullName, objectMember.Name, objectMember.DeclaringType.FullName));
                }
            }
            else if (Helper.IsEnumType(edmMember.TypeUsage.EdmType))
            {
                Debug.Assert(
                    Helper.IsEnumType(objectMember.TypeUsage.EdmType),
                    "Both types are expected to by EnumTypes. For non-matching types we should have already thrown.");

                ValidateEnumTypeMapping((EnumType)edmMember.TypeUsage.EdmType, (EnumType)objectMember.TypeUsage.EdmType);
            }
            else
            {
                EdmType edmMemberType;
                EdmType objectMemberType;

                if (BuiltInTypeKind.AssociationEndMember
                    == edmMember.BuiltInTypeKind)
                {
                    edmMemberType = ((RefType)edmMember.TypeUsage.EdmType).ElementType;
                    objectMemberType = ((RefType)objectMember.TypeUsage.EdmType).ElementType;
                }
                else if (BuiltInTypeKind.NavigationProperty == edmMember.BuiltInTypeKind
                         &&
                         Helper.IsCollectionType(edmMember.TypeUsage.EdmType))
                {
                    edmMemberType = ((CollectionType)edmMember.TypeUsage.EdmType).TypeUsage.EdmType;
                    objectMemberType = ((CollectionType)objectMember.TypeUsage.EdmType).TypeUsage.EdmType;
                }
                else
                {
                    edmMemberType = edmMember.TypeUsage.EdmType;
                    objectMemberType = objectMember.TypeUsage.EdmType;
                }

                if (edmMemberType.Identity
                    != ObjectItemCollection.TryGetMappingCSpaceTypeIdentity(objectMemberType))
                {
                    throw new MappingException(
                        Strings.Mapping_Default_OCMapping_Invalid_MemberType(
                            edmMember.TypeUsage.EdmType.FullName, edmMember.Name, edmMember.DeclaringType.FullName,
                            objectMember.TypeUsage.EdmType.FullName, objectMember.Name, objectMember.DeclaringType.FullName));
                }
            }
        }
예제 #29
0
 internal static bool IsAssociationEndMember(EdmMember member)
 {
     return(BuiltInTypeKind.AssociationEndMember == member.BuiltInTypeKind);
 }
예제 #30
0
 // <summary>
 // Create a nested property ref for a simple property. Delegates to the function
 // above
 // </summary>
 // <param name="p"> the simple property </param>
 // <returns> a nestedPropertyRef </returns>
 internal PropertyRef CreateNestedPropertyRef(md.EdmMember p)
 {
     return(CreateNestedPropertyRef(new SimplePropertyRef(p)));
 }
예제 #31
0
 internal static bool IsEdmProperty(EdmMember member)
 {
     return(BuiltInTypeKind.EdmProperty == member.BuiltInTypeKind);
 }
예제 #32
0
 private static bool MemberMatchesByConvention(PropertyInfo clrProperty, EdmMember cspaceMember)
 {
     return clrProperty.Name == cspaceMember.Name;
 }
 /// <summary>
 /// Constrcut a new member mapping metadata object
 /// </summary>
 /// <param name="edmMember"></param>
 /// <param name="clrMember"></param>
 protected ObjectMemberMapping(EdmMember edmMember, EdmMember clrMember)
 {
     Debug.Assert(edmMember.BuiltInTypeKind == clrMember.BuiltInTypeKind, "BuiltInTypeKind must be the same");
     m_edmMember = edmMember;
     m_clrMember = clrMember;
 }
예제 #34
0
 private static bool NonPrimitiveMemberMatchesByConvention(PropertyInfo clrProperty, EdmMember cspaceMember)
 {
     return(!clrProperty.PropertyType.IsValueType() && !clrProperty.PropertyType.IsAssignableFrom(typeof(string)) &&
            clrProperty.Name == cspaceMember.Name);
 }
예제 #35
0
 // <summary>
 // Validates a EdmMember object to determine if it can be added to this type's
 // Members collection. If this method returns without throwing, it is assumed
 // the member is valid.
 // </summary>
 // <param name="member"> The member to validate </param>
 // <exception cref="System.ArgumentException">Thrown if the member is not a EdmProperty</exception>
 internal override void ValidateMemberForAdd(EdmMember member)
 {
     Debug.Assert(Helper.IsEdmProperty(member), "Only members of type Property may be added to Row types.");
 }
 protected virtual void Visit(EdmMember edmMember)
 {
     Visit(edmMember.TypeUsage);
 }
예제 #37
0
 internal abstract void ValidateMemberForAdd(EdmMember member);
예제 #38
0
 private static bool MemberMatchesByConvention(PropertyInfo clrProperty, EdmMember cspaceMember)
 {
     return(clrProperty.Name == cspaceMember.Name);
 }
예제 #39
0
        internal virtual bool HasMember(EdmMember member)
        {
            DebugCheck.NotNull(member);

            return(_members.Contains(member));
        }
 private static string GetType(EdmMember edmMember)
 {
     var primitiveType = edmMember.TypeUsage.EdmType as PrimitiveType;
     string type = primitiveType != null && primitiveType.ClrEquivalentType != null
                     ? primitiveType.ClrEquivalentType.FullName
                     : edmMember.TypeUsage.EdmType.FullName;
     return type;
 }
 // <summary>
 // Validates a EdmMember object to determine if it can be added to this type's
 // Members collection. If this method returns without throwing, it is assumed
 // the member is valid.
 // </summary>
 // <param name="member"> The member to validate </param>
 // <exception cref="System.ArgumentException">Thrown if the member is not an AssociationEndMember</exception>
 internal override void ValidateMemberForAdd(EdmMember member)
 {
     Debug.Assert(
         (member is AssociationEndMember),
         "Only members of type AssociationEndMember may be added to Association definitions.");
 }
        internal static string GetVariableType(SqlGenerator sqlGenerator, EdmMember column)
        {
            DebugCheck.NotNull(sqlGenerator);
            DebugCheck.NotNull(column);

            var columnType 
                = SqlGenerator.GenerateSqlForStoreType(sqlGenerator.SqlVersion, column.TypeUsage);

            if (columnType == "rowversion"
                || columnType == "timestamp")
            {
                // rowversion and timestamp are intrinsically read-only. use binary to gather server generated
                // values for these types.
                columnType = "binary(8)";
            }

            return columnType;
        }
            /// <summary>
            ///     Given default values for children members, produces a new default expression for the requested (parent) member.
            /// </summary>
            /// <param name="node"> Parent member </param>
            /// <returns> Default value for parent member </returns>
            internal PropagatorResult Visit(EdmMember node)
            {
                PropagatorResult result;
                var nodeType = Helper.GetModelTypeUsage(node);

                if (Helper.IsScalarType(nodeType.EdmType))
                {
                    GetPropagatorResultForPrimitiveType(Helper.AsPrimitive(nodeType.EdmType), out result);
                }
                else
                {
                    // Construct a new 'complex type' (really any structural type) member.
                    var structuralType = (StructuralType)nodeType.EdmType;
                    var members = TypeHelpers.GetAllStructuralMembers(structuralType);

                    var args = new PropagatorResult[members.Count];
                    for (var ordinal = 0; ordinal < members.Count; ordinal++)
                        //                    foreach (EdmMember member in members)
                    {
                        args[ordinal] = Visit(members[ordinal]);
                    }

                    result = PropagatorResult.CreateStructuralValue(args, structuralType, false);
                }

                return result;
            }
        public bool EmitMember(
            TypeBuilder typeBuilder, EdmMember member, PropertyBuilder propertyBuilder, PropertyInfo baseProperty,
            BaseProxyImplementor baseImplementor)
        {
            if (_members.Contains(member))
            {
                var baseGetter = baseProperty.GetGetMethod(true);
                const MethodAttributes getterAttributes =
                    MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Virtual;
                var getterAccess = baseGetter.Attributes & MethodAttributes.MemberAccessMask;

                // Define field to store interceptor Func
                // Signature of interceptor Func delegate is as follows:
                //
                //    bool intercept(ProxyType proxy, PropertyType propertyValue)
                //
                // where
                //     PropertyType is the type of the Property, such as ICollection<Customer>,
                //     ProxyType is the type of the proxy object,
                //     propertyValue is the value returned from the proxied type's property getter.

                var interceptorType = typeof(Func<,,>).MakeGenericType(typeBuilder, baseProperty.PropertyType, typeof(bool));
                var interceptorInvoke = TypeBuilder.GetMethod(interceptorType, typeof(Func<,,>).GetMethod("Invoke"));
                var interceptorField = typeBuilder.DefineField(
                    GetInterceptorFieldName(baseProperty.Name), interceptorType, FieldAttributes.Private | FieldAttributes.Static);

                // Define a property getter override in the proxy type
                var getterBuilder = typeBuilder.DefineMethod(
                    "get_" + baseProperty.Name, getterAccess | getterAttributes, baseProperty.PropertyType, Type.EmptyTypes);
                var generator = getterBuilder.GetILGenerator();

                // Emit instructions for the following call:
                //   T value = base.SomeProperty;
                //   if(this._interceptorForSomeProperty(this, value))
                //   {  return value; }
                //   return base.SomeProperty;
                // where _interceptorForSomeProperty represents the interceptor Func field.

                var lableTrue = generator.DefineLabel();
                generator.DeclareLocal(baseProperty.PropertyType); // T value
                generator.Emit(OpCodes.Ldarg_0); // call base.SomeProperty
                generator.Emit(OpCodes.Call, baseGetter); // call to base property getter
                generator.Emit(OpCodes.Stloc_0); // value = result
                generator.Emit(OpCodes.Ldarg_0); // load this
                generator.Emit(OpCodes.Ldfld, interceptorField); // load this._interceptor
                generator.Emit(OpCodes.Ldarg_0); // load this
                generator.Emit(OpCodes.Ldloc_0); // load value
                generator.Emit(OpCodes.Callvirt, interceptorInvoke); // call to interceptor delegate with (this, value)
                generator.Emit(OpCodes.Brtrue_S, lableTrue); // if true, just return
                generator.Emit(OpCodes.Ldarg_0); // else, call the base propertty getter again
                generator.Emit(OpCodes.Call, baseGetter); // call to base property getter
                generator.Emit(OpCodes.Ret);
                generator.MarkLabel(lableTrue);
                generator.Emit(OpCodes.Ldloc_0);
                generator.Emit(OpCodes.Ret);

                propertyBuilder.SetGetMethod(getterBuilder);

                baseImplementor.AddBasePropertyGetter(baseProperty);
                return true;
            }
            return false;
        }
 private static PrimitiveType ThrowGetStorePrimitiveType(
     Dictionary<string, PrimitiveType> storeNameToPrimitive, string typeName, EdmMember edmMember)
 {
     PrimitiveType storePrimitiveType;
     if (false == storeNameToPrimitive.TryGetValue(typeName, out storePrimitiveType))
     {
         throw new NotSupportedException(
             String.Format(
                 CultureInfo.CurrentCulture, Resources.ErrorIncompatibleTypeForProvider, edmMember.TypeUsage.EdmType.Name,
                 edmMember.Name));
     }
     return storePrimitiveType;
 }
        /// <summary>
        /// Tries and get the mapping ospace member for the given edmMember and the ospace type
        /// </summary>
        /// <param name="edmMember"></param>
        /// <param name="objectType"></param>
        /// <returns></returns
        private static EdmMember GetObjectMember(EdmMember edmMember, StructuralType objectType)
        {
            // Assuming that we will have a single member in O-space for a member in C space
            EdmMember objectMember;
            if (!objectType.Members.TryGetValue(edmMember.Name, false /*ignoreCase*/, out objectMember))
            {
                throw new MappingException(
                    Strings.Mapping_Default_OCMapping_Clr_Member(
                        edmMember.Name, edmMember.DeclaringType.FullName, objectType.FullName));
            }

            return objectMember;
        }
 internal override void ValidateMemberForAdd(EdmMember member)
 {
 }
            /// <summary>
            ///     Returns a placeholder for a specific metadata member.
            /// </summary>
            /// <param name="member"> EdmMember for which to produce a placeholder. </param>
            /// <returns> Placeholder element for the given member. </returns>
            private PropagatorResult CreateMemberPlaceholder(EdmMember member)
            {
                DebugCheck.NotNull(member);

                return Visit(member);
            }
예제 #49
0
 internal virtual bool HasMember(EdmMember member)
 {
     return(this._members.Contains(member));
 }
예제 #50
0
 // Generates T-SQL describing a member
 // Requires: member must belong to an entity type (a safe requirement for DML
 // SQL gen, where we only access table columns)
 internal static string GenerateMemberTSql(EdmMember member)
 {
     return SqlGenerator.QuoteIdentifier(member.Name);
 }
예제 #51
0
 /// <summary>
 ///     Returns a model (C-Space) typeusage for the given member typeusage. if the type is already in c-space, it returns
 ///     the given typeusage. The typeUsage returned is created by invoking the provider service to map from provider
 ///     specific type to model type.
 /// </summary>
 /// <param name="member"> EdmMember </param>
 /// <returns> the respective Model (C-Space) typeusage </returns>
 internal static TypeUsage GetModelTypeUsage(EdmMember member)
 {
     return(GetModelTypeUsage(member.TypeUsage));
 }