/// <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; }
// <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; }
/// <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; }
/// <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); }
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); }
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); }
/// <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); }
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; }
private static bool NonPrimitiveMemberMatchesByConvention(PropertyInfo clrProperty, EdmMember cspaceMember) { return !clrProperty.PropertyType.IsValueType() && !clrProperty.PropertyType.IsAssignableFrom(typeof(string)) && clrProperty.Name == cspaceMember.Name; }
/// <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); }
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); } }
/// <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."); }
// <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); }
/// <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."); }
/// <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; }
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)); } } }
internal static bool IsAssociationEndMember(EdmMember member) { return(BuiltInTypeKind.AssociationEndMember == member.BuiltInTypeKind); }
// <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))); }
internal static bool IsEdmProperty(EdmMember member) { return(BuiltInTypeKind.EdmProperty == member.BuiltInTypeKind); }
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; }
private static bool NonPrimitiveMemberMatchesByConvention(PropertyInfo clrProperty, EdmMember cspaceMember) { return(!clrProperty.PropertyType.IsValueType() && !clrProperty.PropertyType.IsAssignableFrom(typeof(string)) && clrProperty.Name == cspaceMember.Name); }
// <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); }
internal abstract void ValidateMemberForAdd(EdmMember member);
private static bool MemberMatchesByConvention(PropertyInfo clrProperty, EdmMember cspaceMember) { return(clrProperty.Name == cspaceMember.Name); }
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); }
internal virtual bool HasMember(EdmMember member) { return(this._members.Contains(member)); }
// 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); }
/// <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)); }