2 using System
.Collections
;
3 using System
.Collections
.Generic
;
4 using System
.Collections
.ObjectModel
;
5 using System
.Data
.Linq
;
6 using System
.Linq
.Expressions
;
7 using System
.Reflection
;
10 using System
.Diagnostics
.CodeAnalysis
;
12 namespace System
.Data
.Linq
.Mapping
{
14 /// A MetaModel is an abstraction representing the mapping between a database and domain objects
16 public abstract class MetaModel
{
18 /// The mapping source that originated this model.
20 public abstract MappingSource MappingSource { get; }
22 /// The type of DataContext type this model describes.
24 public abstract Type ContextType { get; }
26 /// The name of the database.
28 public abstract string DatabaseName { get; }
30 /// The CLR type that implements IProvider to use as a provider.
32 public abstract Type ProviderType { get; }
34 /// Gets the MetaTable associated with a given type.
36 /// <param name="rowType">The CLR row type.</param>
37 /// <returns>The MetaTable if one exists, otherwise null.</returns>
38 public abstract MetaTable
GetTable(Type rowType
);
40 /// Gets the MetaFunction corresponding to a database function: user-defined function, table-valued function or stored-procedure.
42 /// <param name="method">The method defined on the DataContext or subordinate class that represents the database function.</param>
43 /// <returns>The MetaFunction if one exists, otherwise null.</returns>
44 public abstract MetaFunction
GetFunction(MethodInfo method
);
46 /// Get an enumeration of all tables.
48 /// <returns>An enumeration of all the MetaTables</returns>
49 [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification
="Non-trivial operations are not suitable for properties.")]
50 public abstract IEnumerable
<MetaTable
> GetTables();
52 /// Get an enumeration of all functions.
54 /// <returns>An enumeration of all the MetaFunctions</returns>
55 [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification
="Non-trivial operations are not suitable for properties.")]
56 public abstract IEnumerable
<MetaFunction
> GetFunctions();
58 /// This method discovers the MetaType for the given Type.
60 public abstract MetaType
GetMetaType(Type type
);
62 /// Internal value used to determine a reference identity for comparing meta models
63 /// without needing to keep track of the actual meta model reference.
65 private object identity
= new object();
66 internal object Identity
{
67 get { return this.identity; }
72 /// A MetaTable represents an abstraction of a database table (or view)
74 public abstract class MetaTable
{
76 /// The MetaModel containing this MetaTable.
78 public abstract MetaModel Model { get; }
80 /// The name of the table as defined by the database.
82 public abstract string TableName { get; }
84 /// The MetaType describing the type of the rows of the table.
86 public abstract MetaType RowType { get; }
88 /// The DataContext method used to perform insert operations
90 public abstract MethodInfo InsertMethod { get; }
92 /// The DataContext method used to perform update operations
94 public abstract MethodInfo UpdateMethod { get; }
96 /// The DataContext method used to perform delete operations
98 public abstract MethodInfo DeleteMethod { get; }
102 /// A MetaType represents the mapping of a domain object type onto a database table's columns.
104 public abstract class MetaType
{
106 /// The MetaModel containing this MetaType.
108 public abstract MetaModel Model { get; }
110 /// The MetaTable using this MetaType for row definition.
112 public abstract MetaTable Table { get; }
114 /// The underlying CLR type.
116 [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification
= "The contexts in which this is available are fairly specific.")]
117 public abstract Type Type { get; }
119 /// The name of the MetaType (same as the CLR type's name).
121 public abstract string Name { get; }
123 /// True if the MetaType is an entity type.
125 public abstract bool IsEntity { get; }
127 /// True if the underlying type can be instantiated as the result of a query.
129 public abstract bool CanInstantiate { get; }
131 /// The member that represents the auto-generated identity column, or null if there is none.
133 public abstract MetaDataMember DBGeneratedIdentityMember { get; }
135 /// The member that represents the row-version or timestamp column, or null if there is none.
137 public abstract MetaDataMember VersionMember { get; }
139 /// The member that represents the inheritance discriminator column, or null if there is none.
141 public abstract MetaDataMember Discriminator { get; }
143 /// True if the type has any persistent member with an UpdateCheck policy other than Never.
145 public abstract bool HasUpdateCheck { get; }
147 /// True if the type is part of a mapped inheritance hierarchy.
149 public abstract bool HasInheritance { get; }
151 /// True if this type defines an inheritance code.
153 public abstract bool HasInheritanceCode { get; }
155 /// The inheritance code defined by this type.
157 public abstract object InheritanceCode { get; }
159 /// True if this type is used as the default of an inheritance hierarchy.
161 public abstract bool IsInheritanceDefault { get; }
163 /// The root type of the inheritance hierarchy.
165 public abstract MetaType InheritanceRoot { get; }
167 /// The base metatype in the inheritance hierarchy.
169 public abstract MetaType InheritanceBase { get; }
171 /// The type that is the default of the inheritance hierarchy.
173 public abstract MetaType InheritanceDefault { get; }
175 /// Gets the MetaType for an inheritance sub type.
177 /// <param name="type">The root or sub type of the inheritance hierarchy.</param>
178 /// <returns>The MetaType.</returns>
179 public abstract MetaType
GetInheritanceType(Type type
);
181 /// Gets type associated with the specified inheritance code.
183 /// <param name="code">The inheritance code</param>
184 /// <returns>The MetaType.</returns>
185 public abstract MetaType
GetTypeForInheritanceCode(object code
);
187 /// Gets an enumeration of all types defined by an inheritance hierarchy.
189 /// <returns>Enumeration of MetaTypes.</returns>
190 public abstract ReadOnlyCollection
<MetaType
> InheritanceTypes { get; }
192 /// Returns true if the MetaType or any base MetaType has an OnLoaded method.
194 public abstract bool HasAnyLoadMethod { get; }
196 /// Returns true if the MetaType or any base MetaType has an OnValidate method.
198 public abstract bool HasAnyValidateMethod { get; }
200 /// Gets an enumeration of the immediate derived types in an inheritance hierarchy.
202 /// <returns>Enumeration of MetaTypes.</returns>
203 public abstract ReadOnlyCollection
<MetaType
> DerivedTypes { get; }
205 /// Gets an enumeration of all the data members (fields and properties).
207 public abstract ReadOnlyCollection
<MetaDataMember
> DataMembers { get; }
209 /// Gets an enumeration of all the persistent data members (fields and properties mapped into database columns).
211 public abstract ReadOnlyCollection
<MetaDataMember
> PersistentDataMembers { get; }
213 /// Gets an enumeration of all the data members that define up the unique identity of the type.
215 public abstract ReadOnlyCollection
<MetaDataMember
> IdentityMembers { get; }
217 /// Gets an enumeration of all the associations.
219 public abstract ReadOnlyCollection
<MetaAssociation
> Associations { get; }
221 /// Gets the MetaDataMember associated with the specified member.
223 /// <param name="member">The CLR member.</param>
224 /// <returns>The MetaDataMember if there is one, otherwise null.</returns>
225 public abstract MetaDataMember
GetDataMember(MemberInfo member
);
227 /// The method called when the entity is first loaded.
229 public abstract MethodInfo OnLoadedMethod { get; }
231 /// The method called to ensure the entity is in a valid state.
233 public abstract MethodInfo OnValidateMethod { get; }
237 /// A MetaDataMember represents the mapping between a domain object's field or property into a database table's column.
239 [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId
= "MetaData", Justification
= "The capitalization was deliberately chosen.")]
240 public abstract class MetaDataMember
{
242 /// The MetaType containing this data member.
244 public abstract MetaType DeclaringType { get; }
246 /// The underlying MemberInfo.
248 public abstract MemberInfo Member { get; }
250 /// The member that actually stores this member's data.
252 public abstract MemberInfo StorageMember { get; }
254 /// The name of the member, same as the MemberInfo name.
256 public abstract string Name { get; }
258 /// The name of the column (or constraint) in the database.
260 public abstract string MappedName { get; }
262 /// The oridinal position of this member in the default layout of query results.
264 public abstract int Ordinal { get; }
266 /// The type of this member.
268 [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification
= "The contexts in which this is available are fairly specific.")]
269 public abstract Type Type { get; }
271 /// True if this member is declared by the specified type.
273 /// <param name="type">Type to check.</param>
274 public abstract bool IsDeclaredBy(MetaType type
);
276 /// The accessor used to get/set the value of this member.
278 public abstract MetaAccessor MemberAccessor { get; }
280 /// The accessor used to get/set the storage value of this member.
282 public abstract MetaAccessor StorageAccessor { get; }
284 /// The accessor used to get/set the deferred value of this member (without causing fetch).
286 public abstract MetaAccessor DeferredValueAccessor { get; }
288 /// The accessor used to get/set the deferred source of this member.
290 public abstract MetaAccessor DeferredSourceAccessor { get; }
292 /// True if this member is defer-loaded by default.
294 public abstract bool IsDeferred { get; }
296 /// True if this member is mapped to a column (or constraint).
298 public abstract bool IsPersistent { get; }
300 /// True if this member defines an association relationship.
302 public abstract bool IsAssociation { get; }
304 /// True if this member is part of the type's identity.
306 public abstract bool IsPrimaryKey { get; }
308 /// True if this member is automatically generated by the database.
310 [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId
= "Db", Justification
= "Conforms to legacy spelling.")]
311 public abstract bool IsDbGenerated { get; }
313 /// True if this member represents the row version or timestamp.
315 public abstract bool IsVersion { get; }
317 /// True if this member represents the inheritance discriminator.
319 public abstract bool IsDiscriminator { get; }
321 /// True if this member's value can be assigned the null value.
323 public abstract bool CanBeNull { get; }
325 /// The type of the database column.
327 [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId
= "Db", Justification
= "Conforms to legacy spelling.")]
328 public abstract string DbType { get; }
330 /// Expression defining a computed column.
332 public abstract string Expression { get; }
334 /// The optimistic concurrency check policy for this member.
336 public abstract UpdateCheck UpdateCheck { get; }
338 /// Specifies for inserts and updates when this member should be read back after the
339 /// operation completes.
341 public abstract AutoSync AutoSync { get; }
343 /// The MetaAssociation corresponding to this member, or null if there is none.
345 public abstract MetaAssociation Association { get; }
347 /// The DataContext method used to perform load operations
349 public abstract MethodInfo LoadMethod { get; }
353 /// A MetaFunction represents the mapping between a context method and a database function.
355 public abstract class MetaFunction
{
357 /// The MetaModel containing this function.
359 public abstract MetaModel Model { get; }
361 /// The underlying context method.
363 public abstract MethodInfo Method { get; }
365 /// The name of the method (same as the MethodInfo's name).
367 public abstract string Name { get; }
369 /// The name of the database function or procedure.
371 public abstract string MappedName { get; }
373 /// True if the function can be composed within a query
375 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId
= "Composable", Justification
="Spelling is correct.")]
376 public abstract bool IsComposable { get; }
378 /// Gets an enumeration of the function parameters.
380 /// <returns></returns>
381 public abstract ReadOnlyCollection
<MetaParameter
> Parameters { get; }
383 /// The return parameter
385 public abstract MetaParameter ReturnParameter { get; }
387 /// True if the stored procedure has multiple result types.
389 public abstract bool HasMultipleResults { get; }
391 /// An enumeration of all the known result row types of a stored-procedure.
393 /// <returns>Enumeration of possible result row types.</returns>
394 public abstract ReadOnlyCollection
<MetaType
> ResultRowTypes { get; }
398 /// A MetaParameter represents the mapping between a method parameter and a database function parameter.
400 public abstract class MetaParameter
{
402 /// The underlying method parameter.
404 public abstract ParameterInfo Parameter { get; }
406 /// The name of the parameter (same as the ParameterInfo's name).
408 public abstract string Name { get; }
410 /// The name of the database function's parameter.
412 public abstract string MappedName { get; }
414 /// The CLR type of the parameter.
416 public abstract Type ParameterType { get; }
418 /// The database type of the parameter.
420 [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId
= "Db", Justification
= "Conforms to legacy spelling.")]
421 public abstract string DbType { get; }
425 /// A MetaAssociation represents an association relationship between two entity types.
427 public abstract class MetaAssociation
{
429 /// The type on the other end of the association.
431 public abstract MetaType OtherType { get; }
433 /// The member on this side that represents the association.
435 public abstract MetaDataMember ThisMember { get; }
437 /// The member on the other side of this association that represents the reverse association (may be null).
439 public abstract MetaDataMember OtherMember { get; }
441 /// A list of members representing the values on this side of the association.
443 public abstract ReadOnlyCollection
<MetaDataMember
> ThisKey { get; }
445 /// A list of members representing the values on the other side of the association.
447 public abstract ReadOnlyCollection
<MetaDataMember
> OtherKey { get; }
449 /// True if the association is OneToMany.
451 public abstract bool IsMany { get; }
453 /// True if the other type is the parent of this type.
455 public abstract bool IsForeignKey { get; }
457 /// True if the association is unique (defines a uniqueness constraint).
459 public abstract bool IsUnique { get; }
461 /// True if the association may be null (key values).
463 public abstract bool IsNullable { get; }
465 /// True if the ThisKey forms the identity (primary key) of the this type.
467 public abstract bool ThisKeyIsPrimaryKey { get; }
469 /// True if the OtherKey forms the identity (primary key) of the other type.
471 public abstract bool OtherKeyIsPrimaryKey { get; }
473 /// Specifies the behavior when the child is deleted (e.g. CASCADE, SET NULL).
474 /// Returns null if no action is specified on delete.
476 public abstract string DeleteRule { get; }
478 /// Specifies whether the object should be deleted when this association
481 public abstract bool DeleteOnNull { get; }
487 public abstract class MetaAccessor
{
489 /// The type of the member accessed by this accessor.
491 [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification
= "The contexts in which this is available are fairly specific.")]
492 public abstract Type Type { get; }
494 /// Gets the value as an object.
496 /// <param name="instance">The instance to get the value from.</param>
497 /// <returns>Value.</returns>
498 public abstract object GetBoxedValue(object instance
);
500 /// Sets the value as an object.
502 /// <param name="instance">The instance to set the value into.</param>
503 /// <param name="value">The value to set.</param>
504 [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification
="Microsoft: Needs to handle classes and structs.")]
505 [SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", Justification
="Unknown reason.")]
506 public abstract void SetBoxedValue(ref object instance
, object value);
508 /// True if the instance has a loaded or assigned value.
510 public virtual bool HasValue(object instance
) {
514 /// True if the instance has an assigned value.
516 public virtual bool HasAssignedValue(object instance
) {
520 /// True if the instance has a value loaded from a deferred source.
522 public virtual bool HasLoadedValue(object instance
) {
528 /// A strongly-typed MetaAccessor. Used for reading from and writing to
531 /// <typeparam name="T">The type of the object</typeparam>
532 /// <typeparam name="V">The type of the accessed member</typeparam>
533 public abstract class MetaAccessor
<TEntity
, TMember
> : MetaAccessor
{
535 /// The underlying CLR type.
537 public override Type Type
{
538 get { return typeof(TMember); }
541 /// Set the boxed value on an instance.
543 public override void SetBoxedValue(ref object instance
, object value) {
544 TEntity tInst
= (TEntity
)instance
;
545 this.SetValue(ref tInst
, (TMember
)value);
549 /// Retrieve the boxed value.
551 public override object GetBoxedValue(object instance
) {
552 return this.GetValue((TEntity
)instance
);
555 /// Gets the strongly-typed value.
557 public abstract TMember
GetValue(TEntity instance
);
559 /// Sets the strongly-typed value
561 [SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", MessageId
= "0#", Justification
= "Unknown reason.")]
562 public abstract void SetValue(ref TEntity instance
, TMember
value);