Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataEntity / System / Data / Metadata / MetadataWorkspace.cs / 1 / MetadataWorkspace.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
//---------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.Common.CommandTrees;
using System.Data.Mapping;
using System.Data.Mapping.Update.Internal;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using System.Reflection;
using System.Data.Mapping.ViewGeneration;
using System.Data.Entity;
using System.Linq;
using System.Data.Common.Utils;
using System.Xml;
namespace System.Data.Metadata.Edm
{
///
/// Runtime Metadata Workspace
///
public sealed class MetadataWorkspace
{
#region Constructors
///
/// Constructs the new instance of runtime metadata workspace
///
public MetadataWorkspace()
{
}
///
/// Create MetadataWorkspace that is populated with ItemCollections for all the spaces that the metadata artifacts provided.
/// All res:// paths will be resolved only from the assemblies returned from the enumerable assembliesToConsider.
///
/// The paths where the metadata artifacts located
/// User specified assemlies to consider
///
/// Throw when assembliesToConsider is empty or contains null, or cannot find the corresponding assemly in it
///
public MetadataWorkspace(IEnumerable paths, IEnumerable assembliesToConsider)
{
EntityUtil.CheckArgumentNull(paths, "paths");
// we are intentionally not checking to see if the paths enumerable is empty
EntityUtil.CheckArgumentContainsNull(ref assembliesToConsider, "assembliesToConsider");
Func resolveReference = (AssemblyName referenceName)=>
{
foreach(Assembly assembly in assembliesToConsider)
{
if (AssemblyName.ReferenceMatchesDefinition(referenceName, assembly.GetName()))
{
return assembly;
}
}
throw EntityUtil.Argument(Strings.AssemblyMissingFromAssembliesToConsider(referenceName.FullName), "assembliesToConsider");
};
CreateMetadataWorkspaceWithResolver(paths, () => assembliesToConsider, resolveReference);
}
private void CreateMetadataWorkspaceWithResolver(IEnumerable paths, Func> wildcardAssemblies, Func resolveReference)
{
EntityUtil.CheckArgumentNull(paths, "paths");
// we are intentionally not checking to see if the paths enumerable is empty
EntityUtil.CheckArgumentNull(wildcardAssemblies, "wildcardAssemblies");
EntityUtil.CheckArgumentNull(resolveReference, "resolveReference");
MetadataArtifactLoader composite = MetadataArtifactLoader.CreateCompositeFromFilePaths(paths.ToArray(), "", new CustomAssemblyResolver(wildcardAssemblies, resolveReference));
// only create the ItemCollection that has corresponding artifacts
DataSpace dataSpace = DataSpace.CSpace;
using (DisposableCollectionWrapper cSpaceReaders = new DisposableCollectionWrapper(composite.CreateReaders(dataSpace)))
{
if (cSpaceReaders.Any())
{
this._itemsCSpace = new EdmItemCollection(cSpaceReaders, composite.GetPaths(dataSpace));
}
}
dataSpace = DataSpace.SSpace;
using (DisposableCollectionWrapper sSpaceReaders = new DisposableCollectionWrapper(composite.CreateReaders(dataSpace)))
{
if (sSpaceReaders.Any())
{
this._itemsSSpace = new StoreItemCollection(sSpaceReaders, composite.GetPaths(dataSpace));
}
}
dataSpace = DataSpace.CSSpace;
using (DisposableCollectionWrapper csSpaceReaders = new DisposableCollectionWrapper(composite.CreateReaders(dataSpace)))
{
if (csSpaceReaders.Any() && null != this._itemsCSpace && null != this._itemsSSpace)
{
this._itemsCSSpace = new StorageMappingItemCollection(this._itemsCSpace, this._itemsSSpace, csSpaceReaders, composite.GetPaths(dataSpace));
}
}
}
#endregion
#region Fields
private EdmItemCollection _itemsCSpace;
private StoreItemCollection _itemsSSpace;
private ObjectItemCollection _itemsOSpace;
private StorageMappingItemCollection _itemsCSSpace;
private DefaultObjectMappingItemCollection _itemsOCSpace;
private List _cacheTokens;
#endregion
#region public static Fields
//The Max EDM version thats going to be supported by the runtime.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")]
public static readonly double MaximumEdmVersionSupported = 1.0;
#endregion
#region Methods
///
/// Get item collection for the space. The ItemCollection is in read only mode as it is
/// part of the workspace.
///
/// The dataspace for the item colelction that should be returned
/// The item collection for the given space
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
public ItemCollection GetItemCollection(DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection;
}
///
/// Register the item collection for the space associated with it.
/// This should be done only once for a space.
/// If a space already has a registered ItemCollection InvalidOperation exception is thrown
///
/// The out parameter collection that needs to be filled up
///
/// if collection argument is null
/// If there is an ItemCollection that has already been registered for collection's space passed in
public void RegisterItemCollection(ItemCollection collection)
{
EntityUtil.CheckArgumentNull(collection, "collection");
ItemCollection existing;
try
{
switch (collection.DataSpace)
{
case DataSpace.CSpace:
if (null == (existing = _itemsCSpace)) {
EdmItemCollection edmCollection = (EdmItemCollection)collection;
if(edmCollection.EdmVersion > MetadataWorkspace.MaximumEdmVersionSupported)
{
throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EdmVersionNotSupportedByRuntime(edmCollection.EdmVersion, MaximumEdmVersionSupported));
}
_itemsCSpace = edmCollection;
}
break;
case DataSpace.SSpace:
if (null == (existing = _itemsSSpace))
{
_itemsSSpace = (StoreItemCollection)collection;
}
break;
case DataSpace.OSpace:
if (null == (existing = _itemsOSpace)) {
_itemsOSpace = (ObjectItemCollection)collection;
}
break;
case DataSpace.CSSpace:
if (null == (existing = _itemsCSSpace)) {
_itemsCSSpace = (StorageMappingItemCollection)collection;
}
break;
default:
Debug.Assert(collection.DataSpace == DataSpace.OCSpace, "Invalid DataSpace Enum value: " + collection.DataSpace);
if (null == (existing = _itemsOCSpace)) {
_itemsOCSpace = (DefaultObjectMappingItemCollection)collection;
}
break;
}
}
catch (InvalidCastException)
{
throw EntityUtil.InvalidCollectionForMapping(collection.DataSpace);
}
if (null != existing)
{
throw EntityUtil.ItemCollectionAlreadyRegistered(collection.DataSpace);
}
// Need to make sure that if the storage mapping Item collection was created with the
// same instances of item collection that are registered for CSpace and SSpace
if (collection.DataSpace == DataSpace.CSpace)
{
if (_itemsCSSpace != null && !object.ReferenceEquals(_itemsCSSpace.EdmItemCollection, collection))
{
throw EntityUtil.InvalidCollectionSpecified(collection.DataSpace);
}
}
if (collection.DataSpace == DataSpace.SSpace)
{
if (_itemsCSSpace != null && !object.ReferenceEquals(_itemsCSSpace.StoreItemCollection, collection))
{
throw EntityUtil.InvalidCollectionSpecified(collection.DataSpace);
}
}
if (collection.DataSpace == DataSpace.CSSpace)
{
if (_itemsCSpace != null && !object.ReferenceEquals(_itemsCSSpace.EdmItemCollection, _itemsCSpace))
{
throw EntityUtil.InvalidCollectionSpecified(collection.DataSpace);
}
if (_itemsSSpace != null && !object.ReferenceEquals(_itemsCSSpace.StoreItemCollection, _itemsSSpace))
{
throw EntityUtil.InvalidCollectionSpecified(collection.DataSpace);
}
}
}
///
/// Add a token for this MetadataWorkspace just so this metadata workspace holds a reference to it, this
/// is for metadata caching to make the workspace marking a particular cache entry is still in used
///
///
internal void AddMetadataEntryToken(object token)
{
if (_cacheTokens == null)
{
_cacheTokens = new List();
}
_cacheTokens.Add(token);
}
///
/// Load metadata from the given assembly
///
/// The assembly from which to load metadata
/// thrown if assembly argument is null
public void LoadFromAssembly(Assembly assembly)
{
EntityUtil.CheckArgumentNull(assembly, "assembly");
ObjectItemCollection collection = (ObjectItemCollection)GetItemCollection(DataSpace.OSpace);
collection.LoadFromAssembly(assembly);
}
///
/// Load metadata from the type's assembly into the OSpace ItemCollection.
/// If type comes from known source, has Ecma or Microsoft PublicKeyToken then the type's assembly is not
/// loaded, but the callingAssembly and its referenced assemblies are loaded.
///
/// The type's assembly is loaded into the OSpace ItemCollection
/// The assembly and its referenced assemblies to load when type is insuffiecent
internal void LoadAssemblyForType(Type type, Assembly callingAssembly)
{
// this exists separately from LoadFromAssembly so that we can handle generics, like IEnumerable
Debug.Assert(null != type, "null type");
ItemCollection collection;
if (TryGetItemCollection(DataSpace.OSpace, out collection))
{ // if OSpace is not loaded - don't register
ObjectItemCollection objItemCollection = (ObjectItemCollection)collection;
if (!objItemCollection.LoadAssemblyForType(type) && (null != callingAssembly))
{
// only load from callingAssembly if all types were filtered
// then loaded referenced assemblies of calling assembly
// attempt automatic discovery of user types
// interesting code paths are ObjectQuery, ObjectQuery, ObjectQuery
// other interesting code paths are ObjectQuery>, ObjectQuery>
// when assemblies is mscorlib, System.Data or System.Data.Entity
objItemCollection.LoadAllReferencedAssemblies(callingAssembly);
}
}
}
///
/// If OSpace is not loaded for the specified EntityType
/// the load metadata from the callingAssembly and its referenced assemblies.
///
/// The CSPace type to verify its OSpace counterpart is loaded
/// The assembly and its referenced assemblies to load when type is insuffiecent
internal void LoadFromEntityType(EntityType type, Assembly callingAssembly)
{
// used by ObjectContext.*GetObjectByKey when the clr type is not available
// so we check the OCMap to find the clr type else attempt to autoload the OSpace from callingAssembly
Debug.Assert(null != type, "null type");
Map map;
if (!TryGetMap(type, DataSpace.OCSpace, out map))
{ // an OCMap is not exist, attempt to load OSpace to retry
LoadAssemblyForType(typeof(System.Data.Objects.DataClasses.IEntityWithKey), callingAssembly);
}
}
///
/// Search for an item with the given identity in the given space.
/// For example, The identity for EdmType is Namespace.Name.
///
///
///
///
///
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// if identity argument passed in is null
/// If the ItemCollection for this space does not have an item with the given identity
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public T GetItem(string identity, DataSpace dataSpace) where T:GlobalItem
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetItem(identity, false /*ignoreCase*/);
}
///
/// Search for an item with the given identity in the given space.
///
///
///
///
///
///
/// if identity or space argument is null
public bool TryGetItem(string identity, DataSpace space, out T item ) where T:GlobalItem
{
item = null;
ItemCollection collection = GetItemCollection(space, false);
return (null != collection) && collection.TryGetItem(identity, false /*ignoreCase*/, out item);
}
///
/// Search for an item with the given identity in the given space.
/// For example, The identity for EdmType is Namespace.Name.
///
///
///
///
///
///
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// if identity argument passed in is null
/// If the ItemCollection for this space does not have an item with the given identity
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public T GetItem(string identity, bool ignoreCase, DataSpace dataSpace) where T : GlobalItem
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetItem(identity, ignoreCase);
}
///
/// Search for an item with the given identity in the given space.
///
///
///
///
///
///
///
/// if identity or space argument is null
public bool TryGetItem(string identity, bool ignoreCase, DataSpace dataSpace, out T item) where T : GlobalItem
{
item = null;
ItemCollection collection = GetItemCollection(dataSpace, false);
return (null != collection) && collection.TryGetItem(identity, ignoreCase, out item);
}
///
/// Returns ReadOnlyCollection of the Items of the given type
/// in the workspace.
///
///
///
///
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public ReadOnlyCollection GetItems(DataSpace dataSpace) where T : GlobalItem
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetItems();
}
///
/// Search for a type metadata with the specified name and namespace name in the given space.
///
/// name of the type
/// namespace of the type
/// Dataspace to search the type for
/// Returns null if no match found.
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// if name or namespaceName arguments passed in are null
/// If the ItemCollection for this space does not have a type with the given name and namespaceName
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public EdmType GetType(string name, string namespaceName, DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetType(name, namespaceName, false /*ignoreCase*/);
}
///
/// Search for a type metadata with the specified name and namespace name in the given space.
///
/// name of the type
/// namespace of the type
/// Dataspace to search the type for
/// The type that needs to be filled with the return value
/// Returns false if no match found.
/// if name, namespaceName or space argument is null
public bool TryGetType(string name, string namespaceName, DataSpace dataSpace, out EdmType type)
{
type = null;
ItemCollection collection = GetItemCollection(dataSpace, false);
return (null != collection) && collection.TryGetType(name, namespaceName, false /*ignoreCase*/, out type);
}
///
/// Search for a type metadata with the specified name and namespace name in the given space.
///
/// name of the type
/// namespace of the type
///
/// Dataspace to search the type for
/// Returns null if no match found.
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// if name or namespaceName arguments passed in are null
/// If the ItemCollection for this space does not have a type with the given name and namespaceName
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public EdmType GetType(string name, string namespaceName, bool ignoreCase, DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetType(name, namespaceName, ignoreCase);
}
///
/// Search for a type metadata with the specified name and namespace name in the given space.
///
/// name of the type
/// namespace of the type
/// Dataspace to search the type for
///
/// The type that needs to be filled with the return value
/// Returns null if no match found.
/// if name, namespaceName or space argument is null
public bool TryGetType(string name, string namespaceName, bool ignoreCase,
DataSpace dataSpace, out EdmType type)
{
type = null;
ItemCollection collection = GetItemCollection(dataSpace, false);
return (null != collection) && collection.TryGetType(name, namespaceName, ignoreCase, out type);
}
///
/// Get an entity container based upon the strong name of the container
/// If no entity container is found, returns null, else returns the first one///
/// name of the entity container
///
/// The EntityContainer
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// if name argument passed in is null
/// If the ItemCollection for this space does not have a EntityContainer with the given name
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public EntityContainer GetEntityContainer(string name, DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetEntityContainer(name);
}
///
/// Get an entity container based upon the strong name of the container
/// If no entity container is found, returns null, else returns the first one///
/// name of the entity container
///
///
/// if either space or name arguments is null
public bool TryGetEntityContainer(string name, DataSpace dataSpace, out EntityContainer entityContainer)
{
entityContainer = null;
// null check exists in call stack, but throws for "identity" not "name"
EntityUtil.GenericCheckArgumentNull(name, "name");
ItemCollection collection = GetItemCollection(dataSpace, false);
return (null != collection) && collection.TryGetEntityContainer(name, out entityContainer);
}
///
/// Get an entity container based upon the strong name of the container
/// If no entity container is found, returns null, else returns the first one///
/// name of the entity container
/// true for case-insensitive lookup
///
/// The EntityContainer
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// if name argument passed in is null
/// If the ItemCollection for this space does not have a EntityContainer with the given name
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public EntityContainer GetEntityContainer(string name, bool ignoreCase, DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetEntityContainer(name, ignoreCase);
}
///
/// Get an entity container based upon the strong name of the container
/// If no entity container is found, returns null, else returns the first one///
/// name of the entity container
/// true for case-insensitive lookup
///
///
/// if name or space argument is null
public bool TryGetEntityContainer(string name, bool ignoreCase,
DataSpace dataSpace, out EntityContainer entityContainer)
{
entityContainer = null;
// null check exists in call stack, but throws for "identity" not "name"
EntityUtil.GenericCheckArgumentNull(name, "name");
ItemCollection collection = GetItemCollection(dataSpace, false);
return (null != collection) && collection.TryGetEntityContainer(name, ignoreCase, out entityContainer);
}
///
/// Get all the overloads of the function with the given name
///
/// name of the function
/// namespace of the function
/// The dataspace for which we need to get the function for
/// A collection of all the functions with the given name in the given data space
/// if space argument is null
/// if name or namespaceName argument is null
/// If ItemCollection has not been registered for the space passed in
/// if functionName argument passed in is null
/// If the ItemCollection for this space does not have a EdmFunction with the given functionName
/// If the name or namespaceName is empty
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public ReadOnlyCollection GetFunctions(string name, string namespaceName, DataSpace dataSpace)
{
return GetFunctions(name, namespaceName, dataSpace, false /*ignoreCase*/);
}
///
/// Get all the overloads of the function with the given name
///
/// name of the function
/// namespace of the function
/// The dataspace for which we need to get the function for
/// true for case-insensitive lookup
/// A collection of all the functions with the given name in the given data space
/// if space argument is null
/// if name or namespaceName argument is null
/// If ItemCollection has not been registered for the space passed in
/// if functionName argument passed in is null
/// If the ItemCollection for this space does not have a EdmFunction with the given functionName
/// If the name or namespaceName is empty
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public ReadOnlyCollection GetFunctions(string name,
string namespaceName,
DataSpace dataSpace,
bool ignoreCase)
{
EntityUtil.CheckStringArgument(name, "name");
EntityUtil.CheckStringArgument(namespaceName, "namespaceName");
ItemCollection collection = GetItemCollection(dataSpace, true);
// Get the function with this full name, which is namespace name plus name
return collection.GetFunctions(namespaceName + "." + name, ignoreCase);
}
///
/// Gets the function as specified by the function key
///
/// name of the function
/// namespace of the function
/// types of the parameters
/// true for case-insensitive lookup
///
/// The function that needs to be returned
/// The function as specified in the function key or null
/// if name, namespaceName, parameterTypes or space argument is null
internal bool TryGetFunction(string name,
string namespaceName,
TypeUsage[] parameterTypes,
bool ignoreCase,
DataSpace dataSpace,
out EdmFunction function)
{
function = null;
EntityUtil.GenericCheckArgumentNull(name, "name");
EntityUtil.GenericCheckArgumentNull(namespaceName, "namespaceName");
ItemCollection collection = GetItemCollection(dataSpace, false);
// Get the function with this full name, which is namespace name plus name
return (null != collection) && collection.TryGetFunction(namespaceName + "." + name, parameterTypes, ignoreCase, out function);
}
///
/// Get the list of primitive types for the given space
///
/// dataspace for which you need the list of primitive types
///
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public ReadOnlyCollection GetPrimitiveTypes(DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetItems();
}
///
/// Get all the items in the data space
///
/// dataspace for which you need the list of items
///
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public ReadOnlyCollection GetItems(DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetItems();
}
///
/// Given the canonical primitive type, get the mapping primitive type in the given dataspace
///
/// primitive type kind
/// dataspace in which one needs to the mapping primitive types
/// The mapped scalar type
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
internal PrimitiveType GetMappedPrimitiveType(PrimitiveTypeKind primitiveTypeKind, DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetMappedPrimitiveType(primitiveTypeKind);
}
///
/// Search for a Mapping metadata with the specified type key.
///
/// type
/// The dataspace that the type for which map needs to be returned belongs to
/// true for case-insensitive lookup
/// space for which you want to get the mapped type
///
/// Returns false if no match found.
internal bool TryGetMap(string typeIdentity, DataSpace typeSpace, bool ignoreCase, DataSpace mappingSpace, out Map map)
{
map = null;
ItemCollection collection = GetItemCollection(mappingSpace, false);
return (null != collection) && ((MappingItemCollection)collection).TryGetMap(typeIdentity, typeSpace, ignoreCase, out map);
}
///
/// Search for a Mapping metadata with the specified type key.
///
/// typeIdentity of the type
/// The dataspace that the type for which map needs to be returned belongs to
/// space for which you want to get the mapped type
/// Thrown if mapping space is not valid
internal Map GetMap(string identity, DataSpace typeSpace, DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return ((MappingItemCollection)collection).GetMap(identity, typeSpace);
}
///
/// Search for a Mapping metadata with the specified type key.
///
///
/// space for which you want to get the mapped type
/// Thrown if mapping space is not valid
internal Map GetMap(GlobalItem item, DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return ((MappingItemCollection)collection).GetMap(item);
}
///
/// Search for a Mapping metadata with the specified type key.
///
///
/// space for which you want to get the mapped type
///
/// Returns false if no match found.
internal bool TryGetMap(GlobalItem item, DataSpace dataSpace, out Map map)
{
map = null;
ItemCollection collection = GetItemCollection(dataSpace, false);
return (null != collection) && ((MappingItemCollection)collection).TryGetMap(item, out map);
}
private ItemCollection RegisterDefaultObjectMappingItemCollection()
{
EdmItemCollection edm = _itemsCSpace as EdmItemCollection;
ObjectItemCollection obj = _itemsOSpace as ObjectItemCollection;
if ((null != edm) && (null != obj))
{
RegisterItemCollection(new DefaultObjectMappingItemCollection(edm, obj));
}
return _itemsOCSpace;
}
///
/// Get item collection for the space, if registered. If returned, the ItemCollection is in read only mode as it is
/// part of the workspace.
///
/// The dataspace for the item collection that should be returned
/// The collection registered for the specified dataspace, if any
/// true if an item collection is currently registered for the specified space; otherwise false .
/// if space argument is null
public bool TryGetItemCollection(DataSpace dataSpace, out ItemCollection collection)
{
collection = GetItemCollection(dataSpace, false);
return (null != collection);
}
///
/// Checks if the space is valid and whether the collection is registered for the given space, and if both are valid,
/// then returns the itemcollection for the given space
///
///
/// if true, will throw
/// Thrown if required and mapping space is not valid or registered
internal ItemCollection GetItemCollection(DataSpace dataSpace, bool required)
{
ItemCollection collection;
switch (dataSpace)
{
case DataSpace.CSpace:
collection = _itemsCSpace;
break;
case DataSpace.OSpace:
collection = _itemsOSpace;
break;
case DataSpace.OCSpace:
collection = _itemsOCSpace ?? RegisterDefaultObjectMappingItemCollection();
break;
case DataSpace.CSSpace:
collection = _itemsCSSpace;
break;
case DataSpace.SSpace:
collection = _itemsSSpace;
break;
default:
if (required) {
Debug.Fail("Invalid DataSpace Enum value: " + dataSpace);
}
collection = null;
break;
}
if (required && (null == collection)) {
throw EntityUtil.NoCollectionForSpace(dataSpace);
}
return collection;
}
///
/// The method returns the OSpace type mapped to the specified Edm Space Type.
/// If the DataSpace of the argument is not CSpace, or the mapped OSpace type
/// cannot be determined, an ArgumentException is thrown.
///
/// The CSpace type to look up
/// The OSpace type mapped to the supplied argument
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm")]
public StructuralType GetObjectSpaceType(StructuralType edmSpaceType)
{
StructuralType objectSpaceType;
if (!this.TryGetObjectSpaceType(edmSpaceType, out objectSpaceType))
{
throw EntityUtil.Argument(Strings.FailedToFindOSpaceTypeMapping(edmSpaceType.Identity));
}
return objectSpaceType;
}
///
/// This method returns the OSpace type mapped to the specified Edm Space Type.
/// If the DataSpace of the argument is not CSpace, or if the mapped OSpace type
/// cannot be determined, the method returns false and sets the out parameter
/// to null.
///
/// The CSpace type to look up
/// The OSpace type mapped to the supplied argument
/// true on success, false on failure
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm")]
public bool TryGetObjectSpaceType(StructuralType edmSpaceType, out StructuralType objectSpaceType)
{
EntityUtil.CheckArgumentNull(edmSpaceType, "edmSpaceType");
if (edmSpaceType.DataSpace != DataSpace.CSpace)
{
throw EntityUtil.Argument(Strings.ArgumentMustBeCSpaceType, "edmSpaceType");
}
objectSpaceType = null;
Map map;
if (!this.TryGetMap(edmSpaceType, DataSpace.OCSpace, out map))
{
return false;
}
ObjectTypeMapping ocMap = map as ObjectTypeMapping;
if (ocMap == null)
{
return false;
}
objectSpaceType = (StructuralType)ocMap.ClrType;
return true;
}
///
/// This method returns the Edm Space type mapped to the OSpace Type parameter. If the
/// DataSpace of the supplied type is not OSpace, or the mapped Edm Space type cannot
/// be determined, an ArgumentException is thrown.
///
/// The OSpace type to look up
/// The CSpace type mapped to the OSpace parameter
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")]
public StructuralType GetEdmSpaceType(StructuralType objectSpaceType)
{
StructuralType edmSpaceType;
if (!this.TryGetEdmSpaceType(objectSpaceType, out edmSpaceType))
{
throw EntityUtil.Argument(Strings.FailedToFindCSpaceTypeMapping(objectSpaceType.Identity));
}
return edmSpaceType;
}
///
/// This method returns the Edm Space type mapped to the OSpace Type parameter. If the
/// DataSpace of the supplied type is not OSpace, or the mapped Edm Space type cannot
/// be determined, the method returns false and sets the out parameter to null.
///
/// The OSpace type to look up
/// The mapped CSpace type
/// true on success, false on failure
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")]
public bool TryGetEdmSpaceType(StructuralType objectSpaceType, out StructuralType edmSpaceType)
{
EntityUtil.CheckArgumentNull(objectSpaceType, "objectSpaceType");
if (objectSpaceType.DataSpace != DataSpace.OSpace)
{
throw EntityUtil.Argument(Strings.ArgumentMustBeOSpaceType, "objectSpaceType");
}
edmSpaceType = null;
Map map;
if (!this.TryGetMap(objectSpaceType, DataSpace.OCSpace, out map))
{
return false;
}
ObjectTypeMapping ocMap = map as ObjectTypeMapping;
if (ocMap == null)
{
return false;
}
edmSpaceType = (StructuralType)ocMap.EdmType;
return true;
}
/////
///// Returns the update or query view for an Extent as a
///// command tree. For a given Extent, MetadataWorkspace will
///// have either a Query view or an Update view but not both.
/////
/////
/////
internal DbQueryCommandTree GetCqtView(EntitySetBase extent)
{
return GetGeneratedView(extent).GetCommandTree(this);
}
///
/// Returns generated update or query view for the given extent.
///
internal GeneratedView GetGeneratedView(EntitySetBase extent)
{
ItemCollection collection = GetItemCollection(DataSpace.CSSpace, true);
return ((StorageMappingItemCollection)collection).GetGeneratedView(extent, this);
}
///
/// Returns a TypeOf/TypeOfOnly Query for a given Extent and Type as a command tree.
///
///
///
internal bool TryGetGeneratedViewOfType(EntitySetBase extent, EntityTypeBase type, bool includeSubtypes, out GeneratedView generatedView)
{
ItemCollection collection = GetItemCollection(DataSpace.CSSpace, true);
return ((StorageMappingItemCollection)collection).TryGetGeneratedViewOfType(this, extent, type, includeSubtypes, out generatedView);
}
///
/// Determines if a target function exists for the given function import.
///
/// Function import (function declared in model entity container)
/// Function target mapping (function to which the import is mapped in the target store)
/// true if a mapped target function exists; false otherwise
internal bool TryGetFunctionImportMapping(EdmFunction functionImport, out FunctionImportMapping targetFunctionMapping)
{
ItemCollection collection = GetItemCollection(DataSpace.CSSpace, true);
return StorageMappingItemCollection.TryGetFunctionImportTarget(functionImport, this, out targetFunctionMapping);
}
///
/// Returns the view loader associated with this workspace,
/// creating a loader if non exists. The loader includes
/// context information used by the update pipeline when
/// processing changes to C-space extents.
///
///
internal ViewLoader GetUpdateViewLoader()
{
if (_itemsCSSpace != null)
{
return _itemsCSSpace.GetUpdateViewLoader();
}
return null;
}
///
/// Takes in a Edm space type usage and converts into an
/// equivalent O space type usage
///
///
///
internal TypeUsage GetOSpaceTypeUsage(TypeUsage edmSpaceTypeUsage)
{
EntityUtil.CheckArgumentNull(edmSpaceTypeUsage, "edmSpaceTypeUsage");
if (edmSpaceTypeUsage.EdmType == null)
{
throw EntityUtil.TypeUsageHasNoEdmType("edmSpaceTypeUsage");
}
EdmType clrType = null;
if (Helper.IsPrimitiveType(edmSpaceTypeUsage.EdmType))
{
ItemCollection collection = GetItemCollection(DataSpace.OSpace, true);
clrType = collection.GetMappedPrimitiveType(((PrimitiveType)edmSpaceTypeUsage.EdmType).PrimitiveTypeKind);
}
else
{
// Check and throw if the OC space doesn't exist
ItemCollection collection = GetItemCollection(DataSpace.OCSpace, true);
// Get the OC map
Map map = ((DefaultObjectMappingItemCollection)collection).GetMap(edmSpaceTypeUsage.EdmType);
clrType = ((ObjectTypeMapping)map).ClrType;
}
Debug.Assert(!Helper.IsPrimitiveType(clrType) ||
object.ReferenceEquals(ClrProviderManifest.Instance.GetFacetDescriptions(clrType),
EdmProviderManifest.Instance.GetFacetDescriptions(clrType.BaseType)),
"these are no longer equal so we can't just use the same set of facets for the new type usage");
// Transfer the facet values
TypeUsage result = TypeUsage.Create(clrType, edmSpaceTypeUsage.Facets);
return result;
}
///
/// Returns true if the item collection for the given space has already been registered else returns false
///
///
///
internal bool IsItemCollectionAlreadyRegistered(DataSpace dataSpace)
{
ItemCollection itemCollection;
return TryGetItemCollection(dataSpace, out itemCollection);
}
///
/// Requires: C, S and CS are registered in this and other
/// Determines whether C, S and CS are equivalent. Useful in determining whether a DbCommandTree
/// is usable within a particular entity connection.
///
/// Other workspace.
/// true is C, S and CS collections are equivalent
internal bool IsMetadataWorkspaceCSCompatible(MetadataWorkspace other)
{
Debug.Assert(this.IsItemCollectionAlreadyRegistered(DataSpace.CSSpace) &&
other.IsItemCollectionAlreadyRegistered(DataSpace.CSSpace),
"requires: C, S and CS are registered in this and other");
bool result = this._itemsCSSpace.MetadataEquals(other._itemsCSSpace);
Debug.Assert(!result ||
(this._itemsCSpace.MetadataEquals(other._itemsCSpace) && this._itemsSSpace.MetadataEquals(other._itemsSSpace)),
"constraint: this.CS == other.CS --> this.S == other.S && this.C == other.C");
return result;
}
///
/// Clear all the metadata cache entries
///
public static void ClearCache()
{
MetadataCache.Clear();
ObjectItemCollection.ViewGenerationAssemblies.Clear();
}
///
/// Creates a new Metadata workspace sharing the (currently defined) item collections
/// and tokens for caching purposes.
///
///
internal MetadataWorkspace ShallowCopy()
{
MetadataWorkspace copy = (MetadataWorkspace)MemberwiseClone();
if (null != copy._cacheTokens) {
copy._cacheTokens = new List(copy._cacheTokens);
}
return copy;
}
///
/// Returns the canonical Model TypeUsage for a given PrimitiveTypeKind
///
/// PrimitiveTypeKind for which a canonical TypeUsage is expected
/// a canonical model TypeUsage
internal TypeUsage GetCanonicalModelTypeUsage(PrimitiveTypeKind primitiveTypeKind)
{
return EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(primitiveTypeKind);
}
///
/// Returns the Model PrimitiveType for a given primitiveTypeKind
///
/// a PrimitiveTypeKind for which a Model PrimitiveType is expected
/// Model PrimitiveType
internal PrimitiveType GetModelPrimitiveType(PrimitiveTypeKind primitiveTypeKind)
{
return EdmProviderManifest.Instance.GetPrimitiveType(primitiveTypeKind);
}
//
// Returns list of "interesting" members for the given EntitySet/EntityType
// Interesting Members are:
// 0. Key members
// 1. Members with C-Side conditions (complex types can not have C-side condition at present)
// 2. Members participating in association end
// 3. Members with ConcurrencyMode 'Fixed'
// 3.1 Complex Members with any child member having Concurrency mode Fixed
// 4. Members included in Update ModificationFunction with Version='Original' (Original = Not Current)
// 4.1 Complex Members in ModificaionFunction if any sub-member is interesting
//
// Note: Key values are not returned because they are immutable and never "interesting"
// Abstract EntityTypes are allowed since their parent attributes can be mapped differently.
///
/// Returns members of a given EntitySet/EntityType for which original values are necessary for determining which tables to modify.
///
/// An EntitySet belonging to the C-Space
/// An EntityType that participates in the given EntitySet
/// Edm Members for which original Value is required
public IEnumerable GetRequiredOriginalValueMembers(EntitySetBase entitySet, EntityTypeBase entityType)
{
EntityUtil.CheckArgumentNull(entitySet, "entitySet");
EntityUtil.CheckArgumentNull(entityType, "entityType");
Debug.Assert(entitySet.EntityContainer != null);
//Check that EntitySet is from CSpace
if (entitySet.EntityContainer.GetDataSpace() != DataSpace.CSpace)
{
AssociationSet associationSet = entitySet as AssociationSet;
if (associationSet != null)
{
throw EntityUtil.AssociationSetNotInCSpace(entitySet.Name);
}
else
{
throw EntityUtil.EntitySetNotInCSpace(entitySet.Name);
}
}
//Check that entityType belongs to entitySet
if (!entitySet.ElementType.IsAssignableFrom(entityType))
{
AssociationSet associationSet = entitySet as AssociationSet;
if (associationSet != null)
{
throw EntityUtil.TypeNotInAssociationSet(entitySet.Name, entitySet.ElementType.FullName, entityType.FullName);
}
else
{
throw EntityUtil.TypeNotInEntitySet(entitySet.Name, entitySet.ElementType.FullName, entityType.FullName);
}
}
StorageMappingItemCollection mappingCollection = (StorageMappingItemCollection)GetItemCollection(DataSpace.CSSpace, true);
return mappingCollection.GetRequiredOriginalValueMembers(new Pair(entitySet, entityType));
}
#endregion
#region Properties
///
/// Returns the QueryCacheManager hosted by this metadata workspace instance
///
internal System.Data.Common.QueryCache.QueryCacheManager GetQueryCacheManager()
{
Debug.Assert(null != _itemsSSpace, "_itemsSSpace must not be null");
return _itemsSSpace.QueryCacheManager;
}
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
//---------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.Common.CommandTrees;
using System.Data.Mapping;
using System.Data.Mapping.Update.Internal;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using System.Reflection;
using System.Data.Mapping.ViewGeneration;
using System.Data.Entity;
using System.Linq;
using System.Data.Common.Utils;
using System.Xml;
namespace System.Data.Metadata.Edm
{
///
/// Runtime Metadata Workspace
///
public sealed class MetadataWorkspace
{
#region Constructors
///
/// Constructs the new instance of runtime metadata workspace
///
public MetadataWorkspace()
{
}
///
/// Create MetadataWorkspace that is populated with ItemCollections for all the spaces that the metadata artifacts provided.
/// All res:// paths will be resolved only from the assemblies returned from the enumerable assembliesToConsider.
///
/// The paths where the metadata artifacts located
/// User specified assemlies to consider
///
/// Throw when assembliesToConsider is empty or contains null, or cannot find the corresponding assemly in it
///
public MetadataWorkspace(IEnumerable paths, IEnumerable assembliesToConsider)
{
EntityUtil.CheckArgumentNull(paths, "paths");
// we are intentionally not checking to see if the paths enumerable is empty
EntityUtil.CheckArgumentContainsNull(ref assembliesToConsider, "assembliesToConsider");
Func resolveReference = (AssemblyName referenceName)=>
{
foreach(Assembly assembly in assembliesToConsider)
{
if (AssemblyName.ReferenceMatchesDefinition(referenceName, assembly.GetName()))
{
return assembly;
}
}
throw EntityUtil.Argument(Strings.AssemblyMissingFromAssembliesToConsider(referenceName.FullName), "assembliesToConsider");
};
CreateMetadataWorkspaceWithResolver(paths, () => assembliesToConsider, resolveReference);
}
private void CreateMetadataWorkspaceWithResolver(IEnumerable paths, Func> wildcardAssemblies, Func resolveReference)
{
EntityUtil.CheckArgumentNull(paths, "paths");
// we are intentionally not checking to see if the paths enumerable is empty
EntityUtil.CheckArgumentNull(wildcardAssemblies, "wildcardAssemblies");
EntityUtil.CheckArgumentNull(resolveReference, "resolveReference");
MetadataArtifactLoader composite = MetadataArtifactLoader.CreateCompositeFromFilePaths(paths.ToArray(), "", new CustomAssemblyResolver(wildcardAssemblies, resolveReference));
// only create the ItemCollection that has corresponding artifacts
DataSpace dataSpace = DataSpace.CSpace;
using (DisposableCollectionWrapper cSpaceReaders = new DisposableCollectionWrapper(composite.CreateReaders(dataSpace)))
{
if (cSpaceReaders.Any())
{
this._itemsCSpace = new EdmItemCollection(cSpaceReaders, composite.GetPaths(dataSpace));
}
}
dataSpace = DataSpace.SSpace;
using (DisposableCollectionWrapper sSpaceReaders = new DisposableCollectionWrapper(composite.CreateReaders(dataSpace)))
{
if (sSpaceReaders.Any())
{
this._itemsSSpace = new StoreItemCollection(sSpaceReaders, composite.GetPaths(dataSpace));
}
}
dataSpace = DataSpace.CSSpace;
using (DisposableCollectionWrapper csSpaceReaders = new DisposableCollectionWrapper(composite.CreateReaders(dataSpace)))
{
if (csSpaceReaders.Any() && null != this._itemsCSpace && null != this._itemsSSpace)
{
this._itemsCSSpace = new StorageMappingItemCollection(this._itemsCSpace, this._itemsSSpace, csSpaceReaders, composite.GetPaths(dataSpace));
}
}
}
#endregion
#region Fields
private EdmItemCollection _itemsCSpace;
private StoreItemCollection _itemsSSpace;
private ObjectItemCollection _itemsOSpace;
private StorageMappingItemCollection _itemsCSSpace;
private DefaultObjectMappingItemCollection _itemsOCSpace;
private List _cacheTokens;
#endregion
#region public static Fields
//The Max EDM version thats going to be supported by the runtime.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")]
public static readonly double MaximumEdmVersionSupported = 1.0;
#endregion
#region Methods
///
/// Get item collection for the space. The ItemCollection is in read only mode as it is
/// part of the workspace.
///
/// The dataspace for the item colelction that should be returned
/// The item collection for the given space
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
public ItemCollection GetItemCollection(DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection;
}
///
/// Register the item collection for the space associated with it.
/// This should be done only once for a space.
/// If a space already has a registered ItemCollection InvalidOperation exception is thrown
///
/// The out parameter collection that needs to be filled up
///
/// if collection argument is null
/// If there is an ItemCollection that has already been registered for collection's space passed in
public void RegisterItemCollection(ItemCollection collection)
{
EntityUtil.CheckArgumentNull(collection, "collection");
ItemCollection existing;
try
{
switch (collection.DataSpace)
{
case DataSpace.CSpace:
if (null == (existing = _itemsCSpace)) {
EdmItemCollection edmCollection = (EdmItemCollection)collection;
if(edmCollection.EdmVersion > MetadataWorkspace.MaximumEdmVersionSupported)
{
throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EdmVersionNotSupportedByRuntime(edmCollection.EdmVersion, MaximumEdmVersionSupported));
}
_itemsCSpace = edmCollection;
}
break;
case DataSpace.SSpace:
if (null == (existing = _itemsSSpace))
{
_itemsSSpace = (StoreItemCollection)collection;
}
break;
case DataSpace.OSpace:
if (null == (existing = _itemsOSpace)) {
_itemsOSpace = (ObjectItemCollection)collection;
}
break;
case DataSpace.CSSpace:
if (null == (existing = _itemsCSSpace)) {
_itemsCSSpace = (StorageMappingItemCollection)collection;
}
break;
default:
Debug.Assert(collection.DataSpace == DataSpace.OCSpace, "Invalid DataSpace Enum value: " + collection.DataSpace);
if (null == (existing = _itemsOCSpace)) {
_itemsOCSpace = (DefaultObjectMappingItemCollection)collection;
}
break;
}
}
catch (InvalidCastException)
{
throw EntityUtil.InvalidCollectionForMapping(collection.DataSpace);
}
if (null != existing)
{
throw EntityUtil.ItemCollectionAlreadyRegistered(collection.DataSpace);
}
// Need to make sure that if the storage mapping Item collection was created with the
// same instances of item collection that are registered for CSpace and SSpace
if (collection.DataSpace == DataSpace.CSpace)
{
if (_itemsCSSpace != null && !object.ReferenceEquals(_itemsCSSpace.EdmItemCollection, collection))
{
throw EntityUtil.InvalidCollectionSpecified(collection.DataSpace);
}
}
if (collection.DataSpace == DataSpace.SSpace)
{
if (_itemsCSSpace != null && !object.ReferenceEquals(_itemsCSSpace.StoreItemCollection, collection))
{
throw EntityUtil.InvalidCollectionSpecified(collection.DataSpace);
}
}
if (collection.DataSpace == DataSpace.CSSpace)
{
if (_itemsCSpace != null && !object.ReferenceEquals(_itemsCSSpace.EdmItemCollection, _itemsCSpace))
{
throw EntityUtil.InvalidCollectionSpecified(collection.DataSpace);
}
if (_itemsSSpace != null && !object.ReferenceEquals(_itemsCSSpace.StoreItemCollection, _itemsSSpace))
{
throw EntityUtil.InvalidCollectionSpecified(collection.DataSpace);
}
}
}
///
/// Add a token for this MetadataWorkspace just so this metadata workspace holds a reference to it, this
/// is for metadata caching to make the workspace marking a particular cache entry is still in used
///
///
internal void AddMetadataEntryToken(object token)
{
if (_cacheTokens == null)
{
_cacheTokens = new List();
}
_cacheTokens.Add(token);
}
///
/// Load metadata from the given assembly
///
/// The assembly from which to load metadata
/// thrown if assembly argument is null
public void LoadFromAssembly(Assembly assembly)
{
EntityUtil.CheckArgumentNull(assembly, "assembly");
ObjectItemCollection collection = (ObjectItemCollection)GetItemCollection(DataSpace.OSpace);
collection.LoadFromAssembly(assembly);
}
///
/// Load metadata from the type's assembly into the OSpace ItemCollection.
/// If type comes from known source, has Ecma or Microsoft PublicKeyToken then the type's assembly is not
/// loaded, but the callingAssembly and its referenced assemblies are loaded.
///
/// The type's assembly is loaded into the OSpace ItemCollection
/// The assembly and its referenced assemblies to load when type is insuffiecent
internal void LoadAssemblyForType(Type type, Assembly callingAssembly)
{
// this exists separately from LoadFromAssembly so that we can handle generics, like IEnumerable
Debug.Assert(null != type, "null type");
ItemCollection collection;
if (TryGetItemCollection(DataSpace.OSpace, out collection))
{ // if OSpace is not loaded - don't register
ObjectItemCollection objItemCollection = (ObjectItemCollection)collection;
if (!objItemCollection.LoadAssemblyForType(type) && (null != callingAssembly))
{
// only load from callingAssembly if all types were filtered
// then loaded referenced assemblies of calling assembly
// attempt automatic discovery of user types
// interesting code paths are ObjectQuery, ObjectQuery, ObjectQuery
// other interesting code paths are ObjectQuery>, ObjectQuery>
// when assemblies is mscorlib, System.Data or System.Data.Entity
objItemCollection.LoadAllReferencedAssemblies(callingAssembly);
}
}
}
///
/// If OSpace is not loaded for the specified EntityType
/// the load metadata from the callingAssembly and its referenced assemblies.
///
/// The CSPace type to verify its OSpace counterpart is loaded
/// The assembly and its referenced assemblies to load when type is insuffiecent
internal void LoadFromEntityType(EntityType type, Assembly callingAssembly)
{
// used by ObjectContext.*GetObjectByKey when the clr type is not available
// so we check the OCMap to find the clr type else attempt to autoload the OSpace from callingAssembly
Debug.Assert(null != type, "null type");
Map map;
if (!TryGetMap(type, DataSpace.OCSpace, out map))
{ // an OCMap is not exist, attempt to load OSpace to retry
LoadAssemblyForType(typeof(System.Data.Objects.DataClasses.IEntityWithKey), callingAssembly);
}
}
///
/// Search for an item with the given identity in the given space.
/// For example, The identity for EdmType is Namespace.Name.
///
///
///
///
///
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// if identity argument passed in is null
/// If the ItemCollection for this space does not have an item with the given identity
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public T GetItem(string identity, DataSpace dataSpace) where T:GlobalItem
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetItem(identity, false /*ignoreCase*/);
}
///
/// Search for an item with the given identity in the given space.
///
///
///
///
///
///
/// if identity or space argument is null
public bool TryGetItem(string identity, DataSpace space, out T item ) where T:GlobalItem
{
item = null;
ItemCollection collection = GetItemCollection(space, false);
return (null != collection) && collection.TryGetItem(identity, false /*ignoreCase*/, out item);
}
///
/// Search for an item with the given identity in the given space.
/// For example, The identity for EdmType is Namespace.Name.
///
///
///
///
///
///
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// if identity argument passed in is null
/// If the ItemCollection for this space does not have an item with the given identity
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public T GetItem(string identity, bool ignoreCase, DataSpace dataSpace) where T : GlobalItem
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetItem(identity, ignoreCase);
}
///
/// Search for an item with the given identity in the given space.
///
///
///
///
///
///
///
/// if identity or space argument is null
public bool TryGetItem(string identity, bool ignoreCase, DataSpace dataSpace, out T item) where T : GlobalItem
{
item = null;
ItemCollection collection = GetItemCollection(dataSpace, false);
return (null != collection) && collection.TryGetItem(identity, ignoreCase, out item);
}
///
/// Returns ReadOnlyCollection of the Items of the given type
/// in the workspace.
///
///
///
///
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public ReadOnlyCollection GetItems(DataSpace dataSpace) where T : GlobalItem
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetItems();
}
///
/// Search for a type metadata with the specified name and namespace name in the given space.
///
/// name of the type
/// namespace of the type
/// Dataspace to search the type for
/// Returns null if no match found.
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// if name or namespaceName arguments passed in are null
/// If the ItemCollection for this space does not have a type with the given name and namespaceName
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public EdmType GetType(string name, string namespaceName, DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetType(name, namespaceName, false /*ignoreCase*/);
}
///
/// Search for a type metadata with the specified name and namespace name in the given space.
///
/// name of the type
/// namespace of the type
/// Dataspace to search the type for
/// The type that needs to be filled with the return value
/// Returns false if no match found.
/// if name, namespaceName or space argument is null
public bool TryGetType(string name, string namespaceName, DataSpace dataSpace, out EdmType type)
{
type = null;
ItemCollection collection = GetItemCollection(dataSpace, false);
return (null != collection) && collection.TryGetType(name, namespaceName, false /*ignoreCase*/, out type);
}
///
/// Search for a type metadata with the specified name and namespace name in the given space.
///
/// name of the type
/// namespace of the type
///
/// Dataspace to search the type for
/// Returns null if no match found.
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// if name or namespaceName arguments passed in are null
/// If the ItemCollection for this space does not have a type with the given name and namespaceName
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public EdmType GetType(string name, string namespaceName, bool ignoreCase, DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetType(name, namespaceName, ignoreCase);
}
///
/// Search for a type metadata with the specified name and namespace name in the given space.
///
/// name of the type
/// namespace of the type
/// Dataspace to search the type for
///
/// The type that needs to be filled with the return value
/// Returns null if no match found.
/// if name, namespaceName or space argument is null
public bool TryGetType(string name, string namespaceName, bool ignoreCase,
DataSpace dataSpace, out EdmType type)
{
type = null;
ItemCollection collection = GetItemCollection(dataSpace, false);
return (null != collection) && collection.TryGetType(name, namespaceName, ignoreCase, out type);
}
///
/// Get an entity container based upon the strong name of the container
/// If no entity container is found, returns null, else returns the first one///
/// name of the entity container
///
/// The EntityContainer
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// if name argument passed in is null
/// If the ItemCollection for this space does not have a EntityContainer with the given name
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public EntityContainer GetEntityContainer(string name, DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetEntityContainer(name);
}
///
/// Get an entity container based upon the strong name of the container
/// If no entity container is found, returns null, else returns the first one///
/// name of the entity container
///
///
/// if either space or name arguments is null
public bool TryGetEntityContainer(string name, DataSpace dataSpace, out EntityContainer entityContainer)
{
entityContainer = null;
// null check exists in call stack, but throws for "identity" not "name"
EntityUtil.GenericCheckArgumentNull(name, "name");
ItemCollection collection = GetItemCollection(dataSpace, false);
return (null != collection) && collection.TryGetEntityContainer(name, out entityContainer);
}
///
/// Get an entity container based upon the strong name of the container
/// If no entity container is found, returns null, else returns the first one///
/// name of the entity container
/// true for case-insensitive lookup
///
/// The EntityContainer
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// if name argument passed in is null
/// If the ItemCollection for this space does not have a EntityContainer with the given name
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public EntityContainer GetEntityContainer(string name, bool ignoreCase, DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetEntityContainer(name, ignoreCase);
}
///
/// Get an entity container based upon the strong name of the container
/// If no entity container is found, returns null, else returns the first one///
/// name of the entity container
/// true for case-insensitive lookup
///
///
/// if name or space argument is null
public bool TryGetEntityContainer(string name, bool ignoreCase,
DataSpace dataSpace, out EntityContainer entityContainer)
{
entityContainer = null;
// null check exists in call stack, but throws for "identity" not "name"
EntityUtil.GenericCheckArgumentNull(name, "name");
ItemCollection collection = GetItemCollection(dataSpace, false);
return (null != collection) && collection.TryGetEntityContainer(name, ignoreCase, out entityContainer);
}
///
/// Get all the overloads of the function with the given name
///
/// name of the function
/// namespace of the function
/// The dataspace for which we need to get the function for
/// A collection of all the functions with the given name in the given data space
/// if space argument is null
/// if name or namespaceName argument is null
/// If ItemCollection has not been registered for the space passed in
/// if functionName argument passed in is null
/// If the ItemCollection for this space does not have a EdmFunction with the given functionName
/// If the name or namespaceName is empty
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public ReadOnlyCollection GetFunctions(string name, string namespaceName, DataSpace dataSpace)
{
return GetFunctions(name, namespaceName, dataSpace, false /*ignoreCase*/);
}
///
/// Get all the overloads of the function with the given name
///
/// name of the function
/// namespace of the function
/// The dataspace for which we need to get the function for
/// true for case-insensitive lookup
/// A collection of all the functions with the given name in the given data space
/// if space argument is null
/// if name or namespaceName argument is null
/// If ItemCollection has not been registered for the space passed in
/// if functionName argument passed in is null
/// If the ItemCollection for this space does not have a EdmFunction with the given functionName
/// If the name or namespaceName is empty
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public ReadOnlyCollection GetFunctions(string name,
string namespaceName,
DataSpace dataSpace,
bool ignoreCase)
{
EntityUtil.CheckStringArgument(name, "name");
EntityUtil.CheckStringArgument(namespaceName, "namespaceName");
ItemCollection collection = GetItemCollection(dataSpace, true);
// Get the function with this full name, which is namespace name plus name
return collection.GetFunctions(namespaceName + "." + name, ignoreCase);
}
///
/// Gets the function as specified by the function key
///
/// name of the function
/// namespace of the function
/// types of the parameters
/// true for case-insensitive lookup
///
/// The function that needs to be returned
/// The function as specified in the function key or null
/// if name, namespaceName, parameterTypes or space argument is null
internal bool TryGetFunction(string name,
string namespaceName,
TypeUsage[] parameterTypes,
bool ignoreCase,
DataSpace dataSpace,
out EdmFunction function)
{
function = null;
EntityUtil.GenericCheckArgumentNull(name, "name");
EntityUtil.GenericCheckArgumentNull(namespaceName, "namespaceName");
ItemCollection collection = GetItemCollection(dataSpace, false);
// Get the function with this full name, which is namespace name plus name
return (null != collection) && collection.TryGetFunction(namespaceName + "." + name, parameterTypes, ignoreCase, out function);
}
///
/// Get the list of primitive types for the given space
///
/// dataspace for which you need the list of primitive types
///
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public ReadOnlyCollection GetPrimitiveTypes(DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetItems();
}
///
/// Get all the items in the data space
///
/// dataspace for which you need the list of items
///
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
public ReadOnlyCollection GetItems(DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetItems();
}
///
/// Given the canonical primitive type, get the mapping primitive type in the given dataspace
///
/// primitive type kind
/// dataspace in which one needs to the mapping primitive types
/// The mapped scalar type
/// if space argument is null
/// If ItemCollection has not been registered for the space passed in
/// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
internal PrimitiveType GetMappedPrimitiveType(PrimitiveTypeKind primitiveTypeKind, DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return collection.GetMappedPrimitiveType(primitiveTypeKind);
}
///
/// Search for a Mapping metadata with the specified type key.
///
/// type
/// The dataspace that the type for which map needs to be returned belongs to
/// true for case-insensitive lookup
/// space for which you want to get the mapped type
///
/// Returns false if no match found.
internal bool TryGetMap(string typeIdentity, DataSpace typeSpace, bool ignoreCase, DataSpace mappingSpace, out Map map)
{
map = null;
ItemCollection collection = GetItemCollection(mappingSpace, false);
return (null != collection) && ((MappingItemCollection)collection).TryGetMap(typeIdentity, typeSpace, ignoreCase, out map);
}
///
/// Search for a Mapping metadata with the specified type key.
///
/// typeIdentity of the type
/// The dataspace that the type for which map needs to be returned belongs to
/// space for which you want to get the mapped type
/// Thrown if mapping space is not valid
internal Map GetMap(string identity, DataSpace typeSpace, DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return ((MappingItemCollection)collection).GetMap(identity, typeSpace);
}
///
/// Search for a Mapping metadata with the specified type key.
///
///
/// space for which you want to get the mapped type
/// Thrown if mapping space is not valid
internal Map GetMap(GlobalItem item, DataSpace dataSpace)
{
ItemCollection collection = GetItemCollection(dataSpace, true);
return ((MappingItemCollection)collection).GetMap(item);
}
///
/// Search for a Mapping metadata with the specified type key.
///
///
/// space for which you want to get the mapped type
///
/// Returns false if no match found.
internal bool TryGetMap(GlobalItem item, DataSpace dataSpace, out Map map)
{
map = null;
ItemCollection collection = GetItemCollection(dataSpace, false);
return (null != collection) && ((MappingItemCollection)collection).TryGetMap(item, out map);
}
private ItemCollection RegisterDefaultObjectMappingItemCollection()
{
EdmItemCollection edm = _itemsCSpace as EdmItemCollection;
ObjectItemCollection obj = _itemsOSpace as ObjectItemCollection;
if ((null != edm) && (null != obj))
{
RegisterItemCollection(new DefaultObjectMappingItemCollection(edm, obj));
}
return _itemsOCSpace;
}
///
/// Get item collection for the space, if registered. If returned, the ItemCollection is in read only mode as it is
/// part of the workspace.
///
/// The dataspace for the item collection that should be returned
/// The collection registered for the specified dataspace, if any
/// true if an item collection is currently registered for the specified space; otherwise false .
/// if space argument is null
public bool TryGetItemCollection(DataSpace dataSpace, out ItemCollection collection)
{
collection = GetItemCollection(dataSpace, false);
return (null != collection);
}
///
/// Checks if the space is valid and whether the collection is registered for the given space, and if both are valid,
/// then returns the itemcollection for the given space
///
///
/// if true, will throw
/// Thrown if required and mapping space is not valid or registered
internal ItemCollection GetItemCollection(DataSpace dataSpace, bool required)
{
ItemCollection collection;
switch (dataSpace)
{
case DataSpace.CSpace:
collection = _itemsCSpace;
break;
case DataSpace.OSpace:
collection = _itemsOSpace;
break;
case DataSpace.OCSpace:
collection = _itemsOCSpace ?? RegisterDefaultObjectMappingItemCollection();
break;
case DataSpace.CSSpace:
collection = _itemsCSSpace;
break;
case DataSpace.SSpace:
collection = _itemsSSpace;
break;
default:
if (required) {
Debug.Fail("Invalid DataSpace Enum value: " + dataSpace);
}
collection = null;
break;
}
if (required && (null == collection)) {
throw EntityUtil.NoCollectionForSpace(dataSpace);
}
return collection;
}
///
/// The method returns the OSpace type mapped to the specified Edm Space Type.
/// If the DataSpace of the argument is not CSpace, or the mapped OSpace type
/// cannot be determined, an ArgumentException is thrown.
///
/// The CSpace type to look up
/// The OSpace type mapped to the supplied argument
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm")]
public StructuralType GetObjectSpaceType(StructuralType edmSpaceType)
{
StructuralType objectSpaceType;
if (!this.TryGetObjectSpaceType(edmSpaceType, out objectSpaceType))
{
throw EntityUtil.Argument(Strings.FailedToFindOSpaceTypeMapping(edmSpaceType.Identity));
}
return objectSpaceType;
}
///
/// This method returns the OSpace type mapped to the specified Edm Space Type.
/// If the DataSpace of the argument is not CSpace, or if the mapped OSpace type
/// cannot be determined, the method returns false and sets the out parameter
/// to null.
///
/// The CSpace type to look up
/// The OSpace type mapped to the supplied argument
/// true on success, false on failure
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm")]
public bool TryGetObjectSpaceType(StructuralType edmSpaceType, out StructuralType objectSpaceType)
{
EntityUtil.CheckArgumentNull(edmSpaceType, "edmSpaceType");
if (edmSpaceType.DataSpace != DataSpace.CSpace)
{
throw EntityUtil.Argument(Strings.ArgumentMustBeCSpaceType, "edmSpaceType");
}
objectSpaceType = null;
Map map;
if (!this.TryGetMap(edmSpaceType, DataSpace.OCSpace, out map))
{
return false;
}
ObjectTypeMapping ocMap = map as ObjectTypeMapping;
if (ocMap == null)
{
return false;
}
objectSpaceType = (StructuralType)ocMap.ClrType;
return true;
}
///
/// This method returns the Edm Space type mapped to the OSpace Type parameter. If the
/// DataSpace of the supplied type is not OSpace, or the mapped Edm Space type cannot
/// be determined, an ArgumentException is thrown.
///
/// The OSpace type to look up
/// The CSpace type mapped to the OSpace parameter
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")]
public StructuralType GetEdmSpaceType(StructuralType objectSpaceType)
{
StructuralType edmSpaceType;
if (!this.TryGetEdmSpaceType(objectSpaceType, out edmSpaceType))
{
throw EntityUtil.Argument(Strings.FailedToFindCSpaceTypeMapping(objectSpaceType.Identity));
}
return edmSpaceType;
}
///
/// This method returns the Edm Space type mapped to the OSpace Type parameter. If the
/// DataSpace of the supplied type is not OSpace, or the mapped Edm Space type cannot
/// be determined, the method returns false and sets the out parameter to null.
///
/// The OSpace type to look up
/// The mapped CSpace type
/// true on success, false on failure
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")]
public bool TryGetEdmSpaceType(StructuralType objectSpaceType, out StructuralType edmSpaceType)
{
EntityUtil.CheckArgumentNull(objectSpaceType, "objectSpaceType");
if (objectSpaceType.DataSpace != DataSpace.OSpace)
{
throw EntityUtil.Argument(Strings.ArgumentMustBeOSpaceType, "objectSpaceType");
}
edmSpaceType = null;
Map map;
if (!this.TryGetMap(objectSpaceType, DataSpace.OCSpace, out map))
{
return false;
}
ObjectTypeMapping ocMap = map as ObjectTypeMapping;
if (ocMap == null)
{
return false;
}
edmSpaceType = (StructuralType)ocMap.EdmType;
return true;
}
/////
///// Returns the update or query view for an Extent as a
///// command tree. For a given Extent, MetadataWorkspace will
///// have either a Query view or an Update view but not both.
/////
/////
/////
internal DbQueryCommandTree GetCqtView(EntitySetBase extent)
{
return GetGeneratedView(extent).GetCommandTree(this);
}
///
/// Returns generated update or query view for the given extent.
///
internal GeneratedView GetGeneratedView(EntitySetBase extent)
{
ItemCollection collection = GetItemCollection(DataSpace.CSSpace, true);
return ((StorageMappingItemCollection)collection).GetGeneratedView(extent, this);
}
///
/// Returns a TypeOf/TypeOfOnly Query for a given Extent and Type as a command tree.
///
///
///
internal bool TryGetGeneratedViewOfType(EntitySetBase extent, EntityTypeBase type, bool includeSubtypes, out GeneratedView generatedView)
{
ItemCollection collection = GetItemCollection(DataSpace.CSSpace, true);
return ((StorageMappingItemCollection)collection).TryGetGeneratedViewOfType(this, extent, type, includeSubtypes, out generatedView);
}
///
/// Determines if a target function exists for the given function import.
///
/// Function import (function declared in model entity container)
/// Function target mapping (function to which the import is mapped in the target store)
/// true if a mapped target function exists; false otherwise
internal bool TryGetFunctionImportMapping(EdmFunction functionImport, out FunctionImportMapping targetFunctionMapping)
{
ItemCollection collection = GetItemCollection(DataSpace.CSSpace, true);
return StorageMappingItemCollection.TryGetFunctionImportTarget(functionImport, this, out targetFunctionMapping);
}
///
/// Returns the view loader associated with this workspace,
/// creating a loader if non exists. The loader includes
/// context information used by the update pipeline when
/// processing changes to C-space extents.
///
///
internal ViewLoader GetUpdateViewLoader()
{
if (_itemsCSSpace != null)
{
return _itemsCSSpace.GetUpdateViewLoader();
}
return null;
}
///
/// Takes in a Edm space type usage and converts into an
/// equivalent O space type usage
///
///
///
internal TypeUsage GetOSpaceTypeUsage(TypeUsage edmSpaceTypeUsage)
{
EntityUtil.CheckArgumentNull(edmSpaceTypeUsage, "edmSpaceTypeUsage");
if (edmSpaceTypeUsage.EdmType == null)
{
throw EntityUtil.TypeUsageHasNoEdmType("edmSpaceTypeUsage");
}
EdmType clrType = null;
if (Helper.IsPrimitiveType(edmSpaceTypeUsage.EdmType))
{
ItemCollection collection = GetItemCollection(DataSpace.OSpace, true);
clrType = collection.GetMappedPrimitiveType(((PrimitiveType)edmSpaceTypeUsage.EdmType).PrimitiveTypeKind);
}
else
{
// Check and throw if the OC space doesn't exist
ItemCollection collection = GetItemCollection(DataSpace.OCSpace, true);
// Get the OC map
Map map = ((DefaultObjectMappingItemCollection)collection).GetMap(edmSpaceTypeUsage.EdmType);
clrType = ((ObjectTypeMapping)map).ClrType;
}
Debug.Assert(!Helper.IsPrimitiveType(clrType) ||
object.ReferenceEquals(ClrProviderManifest.Instance.GetFacetDescriptions(clrType),
EdmProviderManifest.Instance.GetFacetDescriptions(clrType.BaseType)),
"these are no longer equal so we can't just use the same set of facets for the new type usage");
// Transfer the facet values
TypeUsage result = TypeUsage.Create(clrType, edmSpaceTypeUsage.Facets);
return result;
}
///
/// Returns true if the item collection for the given space has already been registered else returns false
///
///
///
internal bool IsItemCollectionAlreadyRegistered(DataSpace dataSpace)
{
ItemCollection itemCollection;
return TryGetItemCollection(dataSpace, out itemCollection);
}
///
/// Requires: C, S and CS are registered in this and other
/// Determines whether C, S and CS are equivalent. Useful in determining whether a DbCommandTree
/// is usable within a particular entity connection.
///
/// Other workspace.
/// true is C, S and CS collections are equivalent
internal bool IsMetadataWorkspaceCSCompatible(MetadataWorkspace other)
{
Debug.Assert(this.IsItemCollectionAlreadyRegistered(DataSpace.CSSpace) &&
other.IsItemCollectionAlreadyRegistered(DataSpace.CSSpace),
"requires: C, S and CS are registered in this and other");
bool result = this._itemsCSSpace.MetadataEquals(other._itemsCSSpace);
Debug.Assert(!result ||
(this._itemsCSpace.MetadataEquals(other._itemsCSpace) && this._itemsSSpace.MetadataEquals(other._itemsSSpace)),
"constraint: this.CS == other.CS --> this.S == other.S && this.C == other.C");
return result;
}
///
/// Clear all the metadata cache entries
///
public static void ClearCache()
{
MetadataCache.Clear();
ObjectItemCollection.ViewGenerationAssemblies.Clear();
}
///
/// Creates a new Metadata workspace sharing the (currently defined) item collections
/// and tokens for caching purposes.
///
///
internal MetadataWorkspace ShallowCopy()
{
MetadataWorkspace copy = (MetadataWorkspace)MemberwiseClone();
if (null != copy._cacheTokens) {
copy._cacheTokens = new List(copy._cacheTokens);
}
return copy;
}
///
/// Returns the canonical Model TypeUsage for a given PrimitiveTypeKind
///
/// PrimitiveTypeKind for which a canonical TypeUsage is expected
/// a canonical model TypeUsage
internal TypeUsage GetCanonicalModelTypeUsage(PrimitiveTypeKind primitiveTypeKind)
{
return EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(primitiveTypeKind);
}
///
/// Returns the Model PrimitiveType for a given primitiveTypeKind
///
/// a PrimitiveTypeKind for which a Model PrimitiveType is expected
/// Model PrimitiveType
internal PrimitiveType GetModelPrimitiveType(PrimitiveTypeKind primitiveTypeKind)
{
return EdmProviderManifest.Instance.GetPrimitiveType(primitiveTypeKind);
}
//
// Returns list of "interesting" members for the given EntitySet/EntityType
// Interesting Members are:
// 0. Key members
// 1. Members with C-Side conditions (complex types can not have C-side condition at present)
// 2. Members participating in association end
// 3. Members with ConcurrencyMode 'Fixed'
// 3.1 Complex Members with any child member having Concurrency mode Fixed
// 4. Members included in Update ModificationFunction with Version='Original' (Original = Not Current)
// 4.1 Complex Members in ModificaionFunction if any sub-member is interesting
//
// Note: Key values are not returned because they are immutable and never "interesting"
// Abstract EntityTypes are allowed since their parent attributes can be mapped differently.
///
/// Returns members of a given EntitySet/EntityType for which original values are necessary for determining which tables to modify.
///
/// An EntitySet belonging to the C-Space
/// An EntityType that participates in the given EntitySet
/// Edm Members for which original Value is required
public IEnumerable GetRequiredOriginalValueMembers(EntitySetBase entitySet, EntityTypeBase entityType)
{
EntityUtil.CheckArgumentNull(entitySet, "entitySet");
EntityUtil.CheckArgumentNull(entityType, "entityType");
Debug.Assert(entitySet.EntityContainer != null);
//Check that EntitySet is from CSpace
if (entitySet.EntityContainer.GetDataSpace() != DataSpace.CSpace)
{
AssociationSet associationSet = entitySet as AssociationSet;
if (associationSet != null)
{
throw EntityUtil.AssociationSetNotInCSpace(entitySet.Name);
}
else
{
throw EntityUtil.EntitySetNotInCSpace(entitySet.Name);
}
}
//Check that entityType belongs to entitySet
if (!entitySet.ElementType.IsAssignableFrom(entityType))
{
AssociationSet associationSet = entitySet as AssociationSet;
if (associationSet != null)
{
throw EntityUtil.TypeNotInAssociationSet(entitySet.Name, entitySet.ElementType.FullName, entityType.FullName);
}
else
{
throw EntityUtil.TypeNotInEntitySet(entitySet.Name, entitySet.ElementType.FullName, entityType.FullName);
}
}
StorageMappingItemCollection mappingCollection = (StorageMappingItemCollection)GetItemCollection(DataSpace.CSSpace, true);
return mappingCollection.GetRequiredOriginalValueMembers(new Pair(entitySet, entityType));
}
#endregion
#region Properties
///
/// Returns the QueryCacheManager hosted by this metadata workspace instance
///
internal System.Data.Common.QueryCache.QueryCacheManager GetQueryCacheManager()
{
Debug.Assert(null != _itemsSSpace, "_itemsSSpace must not be null");
return _itemsSSpace.QueryCacheManager;
}
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.