Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Data.Entity / System / Data / Metadata / Edm / NavigationProperty.cs
blobe8525f7cca07e625b6792dea42bea08916077775
1 //---------------------------------------------------------------------
2 // <copyright file="NavigationProperty.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 // </copyright>
5 //
6 // @owner Microsoft
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
9 using System.Collections.Generic;
10 using System.Data.Common;
11 using System.Diagnostics;
12 using System.Threading;
13 using System.Linq;
15 namespace System.Data.Metadata.Edm
17 /// <summary>
18 /// Represent the edm navigation property class
19 /// </summary>
20 public sealed class NavigationProperty : EdmMember
22 #region Constructors
23 /// <summary>
24 /// Initializes a new instance of the navigation property class
25 /// </summary>
26 /// <param name="name">name of the navigation property</param>
27 /// <param name="typeUsage">TypeUsage object containing the navigation property type and its facets</param>
28 /// <exception cref="System.ArgumentNullException">Thrown if name or typeUsage arguments are null</exception>
29 /// <exception cref="System.ArgumentException">Thrown if name argument is empty string</exception>
30 internal NavigationProperty(string name, TypeUsage typeUsage)
31 : base(name, typeUsage)
33 EntityUtil.CheckStringArgument(name, "name");
34 EntityUtil.GenericCheckArgumentNull(typeUsage, "typeUsage");
35 _accessor = new NavigationPropertyAccessor(name);
38 /// <summary>
39 /// Initializes a new OSpace instance of the property class
40 /// </summary>
41 /// <param name="name">name of the property</param>
42 /// <param name="typeUsage">TypeUsage object containing the property type and its facets</param>
43 /// <param name="propertyInfo">for the property</param>
44 internal NavigationProperty(string name, TypeUsage typeUsage, System.Reflection.PropertyInfo propertyInfo)
45 : this(name, typeUsage)
47 System.Diagnostics.Debug.Assert(name == propertyInfo.Name, "different PropertyName?");
48 if (null != propertyInfo)
50 System.Reflection.MethodInfo method;
52 method = propertyInfo.GetGetMethod();
53 PropertyGetterHandle = ((null != method) ? method.MethodHandle : default(System.RuntimeMethodHandle));
56 #endregion
58 /// <summary>
59 /// Returns the kind of the type
60 /// </summary>
61 public override BuiltInTypeKind BuiltInTypeKind { get { return BuiltInTypeKind.NavigationProperty; } }
63 #region Fields
64 internal const string RelationshipTypeNamePropertyName = "RelationshipType";
65 internal const string ToEndMemberNamePropertyName = "ToEndMember";
66 private RelationshipType _relationshipType;
67 private RelationshipEndMember _toEndMember;
68 private RelationshipEndMember _fromEndMember;
70 /// <summary>Store the handle, allowing the PropertyInfo/MethodInfo/Type references to be GC'd</summary>
71 internal readonly System.RuntimeMethodHandle PropertyGetterHandle;
73 /// <summary>cached dynamic methods to access the property values from a CLR instance</summary>
74 private readonly NavigationPropertyAccessor _accessor;
75 #endregion
77 /// <summary>
78 /// Gets/Sets the relationship type that this navigation property operates on
79 /// </summary>
80 /// <exception cref="System.InvalidOperationException">Thrown if the NavigationProperty instance is in ReadOnly state</exception>
81 [MetadataProperty(BuiltInTypeKind.RelationshipType, false)]
82 public RelationshipType RelationshipType
84 get
86 return _relationshipType;
88 internal set
90 _relationshipType = value;
94 /// <summary>
95 /// Gets/Sets the to relationship end member in the navigation
96 /// </summary>
97 /// <exception cref="System.InvalidOperationException">Thrown if the NavigationProperty instance is in ReadOnly state</exception>
98 [MetadataProperty(BuiltInTypeKind.RelationshipEndMember, false)]
99 public RelationshipEndMember ToEndMember
103 return _toEndMember;
105 internal set
107 _toEndMember = value;
111 /// <summary>
112 /// Gets/Sets the from relationship end member in the navigation
113 /// </summary>
114 /// <exception cref="System.InvalidOperationException">Thrown if the NavigationProperty instance is in ReadOnly state</exception>
115 [MetadataProperty(BuiltInTypeKind.RelationshipEndMember, false)]
116 public RelationshipEndMember FromEndMember
120 return _fromEndMember;
122 internal set
124 _fromEndMember = value;
128 internal NavigationPropertyAccessor Accessor
130 get { return _accessor; }
133 /// <summary>
134 /// Where the given navigation property is on the dependent end of a referential constraint,
135 /// returns the foreign key properties. Otherwise, returns an empty set. We will return the members in the order
136 /// of the principal end key properties.
137 /// </summary>
138 /// <returns>Foreign key properties</returns>
139 public IEnumerable<EdmProperty> GetDependentProperties()
141 // Get the declared type
142 AssociationType associationType = (AssociationType)this.RelationshipType;
143 Debug.Assert(
144 associationType.ReferentialConstraints != null,
145 "ReferenceConstraints cannot be null");
147 if (associationType.ReferentialConstraints.Count > 0)
149 ReferentialConstraint rc = associationType.ReferentialConstraints[0];
150 RelationshipEndMember dependentEndMember = rc.ToRole;
152 if (dependentEndMember.EdmEquals(this.FromEndMember))
154 //Order the dependant properties in the order of principal end's key members.
155 var keyMembers = rc.FromRole.GetEntityType().KeyMembers;
156 var dependantProperties = new List<EdmProperty>(keyMembers.Count);
157 for (int i = 0; i < keyMembers.Count; i++)
159 dependantProperties.Add(rc.ToProperties[rc.FromProperties.IndexOf(((EdmProperty)keyMembers[i]))]);
161 return dependantProperties.AsReadOnly();
165 return Enumerable.Empty<EdmProperty>();