1 //---------------------------------------------------------------------
2 // <copyright file="EntityTypeBase.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
8 //---------------------------------------------------------------------
9 namespace System.Data.Metadata.Edm
12 using System.Collections.Generic;
13 using System.Diagnostics;
16 /// Represents the Entity Type
18 public abstract class EntityTypeBase : StructuralType
22 /// Initializes a new instance of Entity Type
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)
32 _keyMembers = new ReadOnlyMetadataCollection<EdmMember>(new MetadataCollection<EdmMember>());
37 private readonly ReadOnlyMetadataCollection<EdmMember> _keyMembers;
38 private string[] _keyMemberNames;
43 /// Returns the list of all the key members for this entity type
45 [MetadataProperty(BuiltInTypeKind.EdmMember, true)]
46 public ReadOnlyMetadataCollection<EdmMember> KeyMembers
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)
55 Debug.Assert(_keyMembers.Count == 0, "Since the base type have keys, current type cannot have keys defined");
56 return ((EntityTypeBase)this.BaseType).KeyMembers;
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
69 internal string[] KeyMemberNames
73 String[] keyNames = _keyMemberNames;
76 keyNames = new string[this.KeyMembers.Count];
77 for (int i = 0; i < keyNames.Length; i++)
79 keyNames[i] = this.KeyMembers[i].Name;
81 _keyMemberNames = keyNames;
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;
92 /// Returns the list of all the key members for this entity type
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)
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");
104 if (!Members.Contains(member))
106 this.AddMember(member);
108 _keyMembers.Source.Add(member);
112 /// Makes this property readonly
114 internal override void SetReadOnly()
118 _keyMembers.Source.SetReadOnly();
124 /// Checks for each property to be non-null and then adds it to the member collection
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)
131 foreach (EdmMember member in members)
133 // Check for each property to be non-null
135 throw EntityUtil.CollectionParameterElementIsNull("members");
137 // Add the property to the member collection
138 entityType.AddMember(member);
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.
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
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)
156 foreach (string keyMember in keyMembers)
158 // Check for each keymember to be non-null
159 if (null == keyMember)
161 throw EntityUtil.CollectionParameterElementIsNull("keyMembers");
163 // Check for whether the key exists in the members collection
165 if (!Members.TryGetValue(keyMember, false, out member))
167 throw EntityUtil.Argument(System.Data.Entity.Strings.InvalidKeyMember(keyMember)); //--- to do, identify the right exception to throw here
169 // Add the key member to the key member collection
170 AddKeyMember(member);