Update Reference Sources to .NET Framework 4.6.1
[mono.git] / mcs / class / referencesource / System.Data.Entity / System / Data / Metadata / Edm / EntityTypeBase.cs
1 //---------------------------------------------------------------------
2 // <copyright file="EntityTypeBase.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //
6 // @owner       [....]
7 // @backupOwner [....]
8 //---------------------------------------------------------------------
9 namespace System.Data.Metadata.Edm
10 {
11     using System;
12     using System.Collections.Generic;
13     using System.Diagnostics;
14
15     /// <summary>
16     /// Represents the Entity Type
17     /// </summary>
18     public abstract class EntityTypeBase : StructuralType
19     {
20         #region Constructors
21         /// <summary>
22         /// Initializes a new instance of Entity Type
23         /// </summary>
24         /// <param name="name">name of the entity type</param>
25         /// <param name="namespaceName">namespace of the entity type</param>
26         /// <param name="version">version of the entity type</param>
27         /// <param name="dataSpace">dataSpace in which this edmtype belongs to</param>
28         /// <exception cref="System.ArgumentNullException">Thrown if either name, namespace or version arguments are null</exception>
29         internal EntityTypeBase(string name, string namespaceName, DataSpace dataSpace)
30             : base(name, namespaceName, dataSpace)
31         {
32             _keyMembers = new ReadOnlyMetadataCollection<EdmMember>(new MetadataCollection<EdmMember>());
33         }
34         #endregion
35
36         #region Fields
37         private readonly ReadOnlyMetadataCollection<EdmMember> _keyMembers;
38         private string[] _keyMemberNames;
39         #endregion
40
41         #region Properties
42         /// <summary>
43         /// Returns the list of all the key members for this entity type
44         /// </summary>
45         [MetadataProperty(BuiltInTypeKind.EdmMember, true)]
46         public ReadOnlyMetadataCollection<EdmMember> KeyMembers
47         {
48             get
49             {
50                 // Since we allow entity types with no keys, we should first check if there are 
51                 // keys defined on the base class. If yes, then return the keys otherwise, return
52                 // the keys defined on this class
53                 if (this.BaseType != null && ((EntityTypeBase)this.BaseType).KeyMembers.Count != 0)
54                 {
55                     Debug.Assert(_keyMembers.Count == 0, "Since the base type have keys, current type cannot have keys defined");
56                     return ((EntityTypeBase)this.BaseType).KeyMembers;
57                 }
58                 else
59                 {
60                     return _keyMembers;
61                 }
62             }
63         }
64
65         /// <summary>
66         /// Returns the list of the member names that form the key for this entity type
67         /// Perf Bug #529294: To cache the list of member names that form the key for the entity type
68         /// </summary>
69         internal string[] KeyMemberNames
70         {
71             get
72             {
73                 String[] keyNames = _keyMemberNames;
74                 if (keyNames == null)
75                 {
76                     keyNames = new string[this.KeyMembers.Count];
77                     for (int i = 0; i < keyNames.Length; i++)
78                     {
79                         keyNames[i] = this.KeyMembers[i].Name;
80                     }
81                     _keyMemberNames = keyNames;
82                 }
83                 Debug.Assert(_keyMemberNames.Length == this.KeyMembers.Count, "This list is out of [....] with the key members count. This property was called before all the keymembers were added");
84                 return _keyMemberNames;
85             }
86         }
87
88         #endregion
89
90         #region Methods
91         /// <summary>
92         /// Returns the list of all the key members for this entity type
93         /// </summary>
94         /// <exception cref="System.ArgumentNullException">if member argument is null</exception>
95         /// <exception cref="System.InvalidOperationException">Thrown if the EntityType has a base type of another EntityTypeBase. In this case KeyMembers should be added to the base type</exception>
96         /// <exception cref="System.InvalidOperationException">If the EntityType instance is in ReadOnly state</exception>
97         internal void AddKeyMember(EdmMember member)
98         {
99             EntityUtil.GenericCheckArgumentNull(member, "member");
100             Util.ThrowIfReadOnly(this);
101             Debug.Assert(this.BaseType == null || ((EntityTypeBase)this.BaseType).KeyMembers.Count == 0,
102                 "Key cannot be added if there is a basetype with keys");
103
104             if (!Members.Contains(member))
105             {
106                 this.AddMember(member);
107             }
108             _keyMembers.Source.Add(member);
109         }
110
111         /// <summary>
112         /// Makes this property readonly
113         /// </summary>
114         internal override void SetReadOnly()
115         {
116             if (!IsReadOnly)
117             {
118                 _keyMembers.Source.SetReadOnly();
119                 base.SetReadOnly();
120             }
121         }
122
123         /// <summary>
124         /// Checks for each property to be non-null and then adds it to the member collection
125         /// </summary>
126         /// <param name="members">members for this type</param>
127         /// <param name="entityType">the membersCollection to which the members should be added</param>
128         internal static void CheckAndAddMembers(IEnumerable<EdmMember> members,
129                                                 EntityType entityType)
130         {
131             foreach (EdmMember member in members)
132             {
133                 // Check for each property to be non-null
134                 if (null == member)
135                     throw EntityUtil.CollectionParameterElementIsNull("members");
136
137                 // Add the property to the member collection
138                 entityType.AddMember(member);
139             }
140         }
141
142
143         /// <summary>
144         /// Checks for each key member to be non-null 
145         /// also check for it to be present in the members collection
146         /// and then adds it to the KeyMembers collection.
147         /// 
148         /// Throw if the key member is not already in the members 
149         /// collection. Cannot do much other than that as the 
150         /// Key members is just an Ienumerable of the names
151         /// of the members.
152         /// </summary>
153         /// <param name="keyMembers">the list of keys (member names) to be added for the given type</param>
154         internal void CheckAndAddKeyMembers(IEnumerable<String> keyMembers)
155         {
156             foreach (string keyMember in keyMembers)
157             {
158                 // Check for each keymember to be non-null
159                 if (null == keyMember)
160                 {
161                     throw EntityUtil.CollectionParameterElementIsNull("keyMembers");
162                 }
163                 // Check for whether the key exists in the members collection
164                 EdmMember member;
165                 if (!Members.TryGetValue(keyMember, false, out member))
166                 {
167                     throw EntityUtil.Argument(System.Data.Entity.Strings.InvalidKeyMember(keyMember)); //--- to do, identify the right exception to throw here
168                 }
169                 // Add the key member to the key member collection 
170                 AddKeyMember(member);
171             }
172         }
173
174         #endregion
175
176     }
177 }