Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Data.Entity / System / Data / Metadata / Edm / EntitySet.cs
blob500c7b2694941f863b77b8bdf1a8a0a893fc7eca
1 //---------------------------------------------------------------------
2 // <copyright file="EntitySet.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 // </copyright>
5 //
6 // @owner Microsoft
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
10 using System;
11 using System.Collections.Generic;
12 using System.Text;
13 using System.Diagnostics;
14 using System.Threading;
15 using System.Data.Common.Utils;
16 using System.Collections.ObjectModel;
18 namespace System.Data.Metadata.Edm
20 /// <summary>
21 /// concrete Class for representing a entity set
22 /// </summary>
23 public class EntitySet : EntitySetBase
25 #region Constructors
26 /// <summary>
27 /// The constructor for constructing the EntitySet with a given name and an entity type
28 /// </summary>
29 /// <param name="name">The name of the EntitySet</param>
30 /// <param name="schema">The db schema</param>
31 /// <param name="table">The db table</param>
32 /// <param name="definingQuery">The provider specific query that should be used to retrieve the EntitySet</param>
33 /// <param name="entityType">The entity type of the entities that this entity set type contains</param>
34 /// <exception cref="System.ArgumentNullException">Thrown if the argument name or entityType is null</exception>
35 internal EntitySet(string name, string schema, string table, string definingQuery, EntityType entityType)
36 : base(name, schema, table, definingQuery, entityType)
39 #endregion
41 #region Fields
42 private ReadOnlyCollection<Tuple<AssociationSet, ReferentialConstraint>> _foreignKeyDependents;
43 private ReadOnlyCollection<Tuple<AssociationSet, ReferentialConstraint>> _foreignKeyPrincipals;
44 private volatile bool _hasForeignKeyRelationships;
45 private volatile bool _hasIndependentRelationships;
46 #endregion
48 #region Properties
49 /// <summary>
50 /// Returns the kind of the type
51 /// </summary>
52 public override BuiltInTypeKind BuiltInTypeKind { get { return BuiltInTypeKind.EntitySet; } }
54 /// <summary>
55 /// Gets/Sets the entity type of this entity set
56 /// </summary>
57 public new EntityType ElementType
59 get
61 return (EntityType)base.ElementType;
65 /// <summary>
66 /// Returns the associations and constraints where "this" EntitySet particpates as the Principal end.
67 /// From the results of this list, you can retrieve the Dependent IRelatedEnds
68 /// </summary>
69 internal ReadOnlyCollection<Tuple<AssociationSet, ReferentialConstraint>> ForeignKeyDependents
71 get
73 if (_foreignKeyDependents == null)
75 InitializeForeignKeyLists();
77 return _foreignKeyDependents;
81 /// <summary>
82 /// Returns the associations and constraints where "this" EntitySet particpates as the Dependent end.
83 /// From the results of this list, you can retrieve the Principal IRelatedEnds
84 /// </summary>
85 internal ReadOnlyCollection<Tuple<AssociationSet, ReferentialConstraint>> ForeignKeyPrincipals
87 get
89 if (_foreignKeyPrincipals == null)
91 InitializeForeignKeyLists();
93 return _foreignKeyPrincipals;
97 /// <summary>
98 /// True if this entity set participates in any foreign key relationships, otherwise false.
99 /// </summary>
100 internal bool HasForeignKeyRelationships
104 if (_foreignKeyPrincipals == null)
106 InitializeForeignKeyLists();
108 return _hasForeignKeyRelationships;
112 /// <summary>
113 /// True if this entity set participates in any independent relationships, otherwise false.
114 /// </summary>
115 internal bool HasIndependentRelationships
119 if (_foreignKeyPrincipals == null)
121 InitializeForeignKeyLists();
123 return _hasIndependentRelationships;
127 #endregion
129 #region Methods
130 private void InitializeForeignKeyLists()
132 var dependents = new List<Tuple<AssociationSet, ReferentialConstraint>>();
133 var principals = new List<Tuple<AssociationSet, ReferentialConstraint>>();
134 bool foundFkRelationship = false;
135 bool foundIndependentRelationship = false;
136 foreach (AssociationSet associationSet in MetadataHelper.GetAssociationsForEntitySet(this))
138 if (associationSet.ElementType.IsForeignKey)
140 foundFkRelationship = true;
141 Debug.Assert(associationSet.ElementType.ReferentialConstraints.Count == 1, "Expected exactly one constraint for FK");
142 ReferentialConstraint constraint = associationSet.ElementType.ReferentialConstraints[0];
143 if (constraint.ToRole.GetEntityType().IsAssignableFrom(this.ElementType) ||
144 this.ElementType.IsAssignableFrom(constraint.ToRole.GetEntityType()))
146 // Dependents
147 dependents.Add(new Tuple<AssociationSet, ReferentialConstraint>(associationSet, constraint));
149 if (constraint.FromRole.GetEntityType().IsAssignableFrom(this.ElementType) ||
150 this.ElementType.IsAssignableFrom(constraint.FromRole.GetEntityType()))
152 // Principals
153 principals.Add(new Tuple<AssociationSet, ReferentialConstraint>(associationSet, constraint));
156 else
158 foundIndependentRelationship = true;
162 _hasForeignKeyRelationships = foundFkRelationship;
163 _hasIndependentRelationships = foundIndependentRelationship;
165 var readOnlyDependents = dependents.AsReadOnly();
166 var readOnlyPrincipals = principals.AsReadOnly();
168 Interlocked.CompareExchange(ref _foreignKeyDependents, readOnlyDependents, null);
169 Interlocked.CompareExchange(ref _foreignKeyPrincipals, readOnlyPrincipals, null);
171 #endregion