internal DbRelatedEntityRef(RelationshipEndMember sourceEnd, RelationshipEndMember targetEnd, DbExpression targetEntityRef) { // Validate that the specified relationship ends are: // 1. Non-null // 2. From the same metadata workspace as that used by the command tree DebugCheck.NotNull(sourceEnd); DebugCheck.NotNull(targetEnd); // Validate that the specified target entity ref is: // 1. Non-null DebugCheck.NotNull(targetEntityRef); // Validate that the specified source and target ends are: // 1. Declared by the same relationship type if (!ReferenceEquals(sourceEnd.DeclaringType, targetEnd.DeclaringType)) { throw new ArgumentException(Strings.Cqt_RelatedEntityRef_TargetEndFromDifferentRelationship, "targetEnd"); } // 2. Not the same end if (ReferenceEquals(sourceEnd, targetEnd)) { throw new ArgumentException(Strings.Cqt_RelatedEntityRef_TargetEndSameAsSourceEnd, "targetEnd"); } // Validate that the specified target end has multiplicity of at most one if (targetEnd.RelationshipMultiplicity != RelationshipMultiplicity.One && targetEnd.RelationshipMultiplicity != RelationshipMultiplicity.ZeroOrOne) { throw new ArgumentException(Strings.Cqt_RelatedEntityRef_TargetEndMustBeAtMostOne, "targetEnd"); } // Validate that the specified target entity ref actually has a ref result type if (!TypeSemantics.IsReferenceType(targetEntityRef.ResultType)) { throw new ArgumentException(Strings.Cqt_RelatedEntityRef_TargetEntityNotRef, "targetEntityRef"); } // Validate that the specified target entity is of a type that can be reached by navigating to the specified relationship end var endType = TypeHelpers.GetEdmType<RefType>(targetEnd.TypeUsage).ElementType; var targetType = TypeHelpers.GetEdmType<RefType>(targetEntityRef.ResultType).ElementType; if (!endType.EdmEquals(targetType) && !TypeSemantics.IsSubTypeOf(targetType, endType)) { throw new ArgumentException(Strings.Cqt_RelatedEntityRef_TargetEntityNotCompatible, "targetEntityRef"); } // Validation succeeded, initialize state _targetEntityRef = targetEntityRef; _targetEnd = targetEnd; _sourceEnd = sourceEnd; }
/// <summary> /// Constructs a new constraint on the relationship /// </summary> /// <param name="fromRole">role from which the relationship originates</param> /// <param name="toRole">role to which the relationship is linked/targeted to</param> /// <param name="toProperties">properties on entity type of from role which take part in the constraint</param> /// <param name="fromProperties">properties on entity type of to role which take part in the constraint</param> /// <exception cref="ArgumentNullException">Argument Null exception if any of the arguments is null</exception> internal ReferentialConstraint( RelationshipEndMember fromRole, RelationshipEndMember toRole, IEnumerable<EdmProperty> fromProperties, IEnumerable<EdmProperty> toProperties) { _fromRole = EntityUtil.GenericCheckArgumentNull(fromRole, "fromRole"); _toRole = EntityUtil.GenericCheckArgumentNull(toRole, "toRole"); _fromProperties = new ReadOnlyMetadataCollection<EdmProperty>( new MetadataCollection<EdmProperty>( EntityUtil.GenericCheckArgumentNull(fromProperties, "fromProperties"))); _toProperties = new ReadOnlyMetadataCollection<EdmProperty>( new MetadataCollection<EdmProperty>( EntityUtil.GenericCheckArgumentNull(toProperties, "toProperties"))); }
/// <summary> /// Constructs a new constraint on the relationship /// </summary> /// <param name="fromRole"> role from which the relationship originates </param> /// <param name="toRole"> role to which the relationship is linked/targeted to </param> /// <param name="toProperties"> properties on entity type of from role which take part in the constraint </param> /// <param name="fromProperties"> properties on entity type of to role which take part in the constraint </param> /// <exception cref="ArgumentNullException">Argument Null exception if any of the arguments is null</exception> public ReferentialConstraint( RelationshipEndMember fromRole, RelationshipEndMember toRole, IEnumerable<EdmProperty> fromProperties, IEnumerable<EdmProperty> toProperties) { _fromRole = Check.NotNull(fromRole, "fromRole"); _toRole = Check.NotNull(toRole, "toRole"); _fromProperties = new ReadOnlyMetadataCollection<EdmProperty>( new MetadataCollection<EdmProperty>( Check.NotNull(fromProperties, "fromProperties"))); _toProperties = new ReadOnlyMetadataCollection<EdmProperty>( new MetadataCollection<EdmProperty>( Check.NotNull(toProperties, "toProperties"))); }
/// <summary> /// Creates a NavigationProperty instance from the specified parameters. /// </summary> /// <param name="name">The name of the navigation property.</param> /// <param name="typeUsage">Specifies the navigation property type and its facets.</param> /// <param name="relationshipType">The relationship type for the navigation.</param> /// <param name="from">The source end member in the navigation.</param> /// <param name="to">The target end member in the navigation.</param> /// <param name="metadataProperties">The metadata properties of the navigation property.</param> /// <returns>The newly created NavigationProperty instance.</returns> public static NavigationProperty Create( string name, TypeUsage typeUsage, RelationshipType relationshipType, RelationshipEndMember from, RelationshipEndMember to, IEnumerable<MetadataProperty> metadataProperties) { Check.NotEmpty(name, "name"); Check.NotNull(typeUsage, "typeUsage"); var instance = new NavigationProperty(name, typeUsage); instance.RelationshipType = relationshipType; instance.FromEndMember = from; instance.ToEndMember = to; if (metadataProperties != null) { instance.AddMetadataProperties(metadataProperties.ToList()); } instance.SetReadOnly(); return instance; }
internal RelProperty(RelationshipType relationshipType, RelationshipEndMember fromEnd, RelationshipEndMember toEnd) { m_relationshipType = relationshipType; m_fromEnd = fromEnd; m_toEnd = toEnd; }
protected virtual void Visit(RelationshipEndMember relationshipEndMember) { Visit(relationshipEndMember.TypeUsage); }
private static StructuralType GetRelationshipEndType(RelationshipEndMember relationshipEndMember) { return ((RefType)relationshipEndMember.TypeUsage.EdmType).ElementType; }
/// <summary> /// Builds up a join between the relationshipset and the entityset corresponding to its toEnd. In essence, /// we produce /// SELECT r, e /// FROM RS as r, OFTYPE(ES, T) as e /// WHERE r.ToEnd = Ref(e) /// /// "T" is the entity type of the toEnd of the relationship. /// </summary> /// <param name="relSet">the relationshipset</param> /// <param name="end">the toEnd of the relationship</param> /// <param name="rsVar">the var representing the relationship instance ("r") in the output subquery</param> /// <param name="esVar">the var representing the entity instance ("e") in the output subquery</param> /// <returns>the join subquery described above</returns> private Node BuildJoinForNavProperty( RelationshipSet relSet, RelationshipEndMember end, out Var rsVar, out Var esVar) { var entitySet = FindTargetEntitySet(relSet, end); // // Build out the ScanTable ops for the relationshipset and the entityset. Add the // var asTableNode = BuildOfTypeTable(relSet, null, out rsVar); var esTableNode = BuildOfTypeTable(entitySet, TypeHelpers.GetElementTypeUsage(end.TypeUsage), out esVar); // // Build up a join between the entityset and the associationset; join on the to-end // var joinPredicate = m_command.BuildComparison( OpType.EQ, m_command.CreateNode(m_command.CreateGetEntityRefOp(end.TypeUsage), m_command.CreateNode(m_command.CreateVarRefOp(esVar))), m_command.CreateNode(m_command.CreatePropertyOp(end), m_command.CreateNode(m_command.CreateVarRefOp(rsVar))) ); var joinNode = m_command.CreateNode( m_command.CreateInnerJoinOp(), asTableNode, esTableNode, joinPredicate); return joinNode; }
private static EntitySetBase FindTargetEntitySet(RelationshipSet relationshipSet, RelationshipEndMember targetEnd) { EntitySetBase entitySet = null; var associationSet = (AssociationSet)relationshipSet; // find the corresponding entityset entitySet = null; foreach (var e in associationSet.AssociationSetEnds) { if (e.CorrespondingAssociationEndMember.EdmEquals(targetEnd)) { entitySet = e.EntitySet; break; } } PlanCompiler.Assert( entitySet != null, "Could not find entity set for relationship set " + relationshipSet + ";association end " + targetEnd); return entitySet; }
internal void WriteReferentialConstraintRoleElement( string roleName, RelationshipEndMember edmAssociationEnd, IEnumerable<EdmProperty> properties) { _xmlWriter.WriteStartElement(roleName); _xmlWriter.WriteAttributeString(XmlConstants.Role, edmAssociationEnd.Name); foreach (var property in properties) { _xmlWriter.WriteStartElement(XmlConstants.PropertyRef); _xmlWriter.WriteAttributeString(XmlConstants.Name, property.Name); _xmlWriter.WriteEndElement(); } _xmlWriter.WriteEndElement(); }
internal void WriteAssociationEndElementHeader(RelationshipEndMember associationEnd) { DebugCheck.NotNull(associationEnd); _xmlWriter.WriteStartElement(XmlConstants.End); _xmlWriter.WriteAttributeString(XmlConstants.Role, associationEnd.Name); var typeName = associationEnd.GetEntityType().Name; _xmlWriter.WriteAttributeString( XmlConstants.TypeAttribute, GetQualifiedTypeName(XmlConstants.Self, typeName)); _xmlWriter.WriteAttributeString( XmlConstants.Multiplicity, RelationshipMultiplicityConverter.MultiplicityToString(associationEnd.RelationshipMultiplicity)); }
protected override void Visit(RelationshipEndMember relationshipEndMember) { int index; if (!AddObjectToSeenListAndHashBuilder(relationshipEndMember, out index)) { return; } AddObjectStartDumpToHashBuilder(relationshipEndMember, index); #region Inner data visit AddObjectContentToHashBuilder(relationshipEndMember.DeleteBehavior); AddObjectContentToHashBuilder(relationshipEndMember.Identity); // Name is covered by Identity AddObjectContentToHashBuilder(relationshipEndMember.IsStoreGeneratedComputed); AddObjectContentToHashBuilder(relationshipEndMember.IsStoreGeneratedIdentity); AddObjectContentToHashBuilder(relationshipEndMember.RelationshipMultiplicity); base.Visit(relationshipEndMember); #endregion AddObjectEndDumpToHashBuilder(); }
/// <summary> /// Dumps the specified Relation End EdmMember metadata instance with the specified decoration /// </summary> /// <param name="end"> The Relation End metadata to dump </param> /// <param name="name"> The decorating block name </param> internal void Dump(RelationshipEndMember end, string name) { Begin(name); Begin( "RelationshipEndMember", "Name", end.Name, //"IsParent", end.IsParent, "RelationshipMultiplicity", Enum.GetName(typeof(RelationshipMultiplicity), end.RelationshipMultiplicity) ); Dump(end.DeclaringType, "DeclaringRelation"); Dump(end.TypeUsage, "EndType"); End("RelationshipEndMember"); End(name); }
/// <summary> /// Creates a NavigationProperty instance from the specified parameters. /// </summary> /// <param name="name">The name of the navigation property.</param> /// <param name="typeUsage">Specifies the navigation property type and its facets.</param> /// <param name="relationshipType">The relationship type for the navigation.</param> /// <param name="from">The source end member in the navigation.</param> /// <param name="to">The target end member in the navigation.</param> /// <returns>The newly created NavigationProperty instance.</returns> public static NavigationProperty Create( string name, TypeUsage typeUsage, RelationshipType relationshipType, RelationshipEndMember from, RelationshipEndMember to) { var instance = new NavigationProperty(name, typeUsage); instance.RelationshipType = relationshipType; instance.FromEndMember = from; instance.ToEndMember = to; instance.SetReadOnly(); return instance; }
private static StructuralType GetRelationshipEndType(RelationshipEndMember relationshipEndMember) { return(((RefType)relationshipEndMember.TypeUsage.EdmType).ElementType); }