Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Mapping / StorageMappingItemCollection.cs / 1305376 / StorageMappingItemCollection.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System;
using System.Data.Common.Utils;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.EntityModel;
using System.Text;
using System.Xml.Serialization;
using System.Xml;
using System.Xml.Schema;
using System.IO;
using System.Data.Common.CommandTrees;
using System.Data.Metadata.Edm;
using System.Data.Mapping.ViewGeneration;
using System.Reflection;
using System.Data.Mapping.ViewGeneration.Utils;
using System.Security.Cryptography;
using System.Xml.XPath;
using System.Linq;
using System.Data.Mapping.Update.Internal;
using som = System.Data.EntityModel.SchemaObjectModel;
using System.Data.Entity;
namespace System.Data.Mapping
{
using OfTypeQVCacheKey = Pair>;
using System.Runtime.Versioning;
///
/// Class for representing a collection of items in Storage Mapping( CS Mapping) space.
///
[CLSCompliant(false)]
public partial class StorageMappingItemCollection : MappingItemCollection
{
#region Fields
//EdmItemCollection that is associated with the MSL Loader.
private EdmItemCollection m_edmCollection;
//StoreItemCollection that is associated with the MSL Loader.
private StoreItemCollection m_storeItemCollection;
private ViewDictionary m_viewDictionary;
private double m_mappingVersion = XmlConstants.UndefinedVersion;
// In this version, we won't allow same types in CSpace to map to different types in store. If the same type
// need to be reused, the store type must be the same. To keep track of this, we need to keep track of the member
// mapping across maps to make sure they are mapped to the same store side.
// The first TypeUsage in the KeyValuePair stores the store equivalent type for the cspace member type and the second
// one store the actual store type to which the member is mapped to.
// For e.g. If the CSpace member of type Edm.Int32 maps to a sspace member of type SqlServer.bigint, then the KeyValuePair
// for the cspace member will contain SqlServer.int (store equivalent for Edm.Int32) and SqlServer.bigint (Actual store type
// to which the member was mapped to)
private Dictionary> m_memberMappings = new Dictionary>();
private ViewLoader _viewLoader;
private Memoizer, ReadOnlyCollection> _cacheRequiredOriginalValueMembers;
#endregion
#region Constructors
///
/// constructor that takes in a list of ffolder or files or a mix of both and
/// creates metadata for mapping in all the files.
///
///
///
///
[ResourceExposure(ResourceScope.Machine)] //Exposes the file path names which are a Machine resource
[ResourceConsumption(ResourceScope.Machine)] //For MetadataArtifactLoader.CreateCompositeFromFilePaths method call but we do not create the file paths in this method
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm")]
public StorageMappingItemCollection(EdmItemCollection edmCollection, StoreItemCollection storeCollection,
params string[] filePaths)
: base(DataSpace.CSSpace)
{
EntityUtil.CheckArgumentNull(edmCollection, "edmCollection");
EntityUtil.CheckArgumentNull(storeCollection, "storeCollection");
EntityUtil.CheckArgumentNull(filePaths, "filePaths");
this.m_edmCollection = edmCollection;
this.m_storeItemCollection = storeCollection;
// Wrap the file paths in instances of the MetadataArtifactLoader class, which provides
// an abstraction and a uniform interface over a diverse set of metadata artifacts.
//
MetadataArtifactLoader composite = null;
List readers = null;
try
{
composite = MetadataArtifactLoader.CreateCompositeFromFilePaths(filePaths, XmlConstants.CSSpaceSchemaExtension);
readers = composite.CreateReaders(DataSpace.CSSpace);
this.Init(edmCollection, storeCollection, readers,
composite.GetPaths(DataSpace.CSSpace), true /*throwOnError*/);
}
finally
{
if (readers != null)
{
Helper.DisposeXmlReaders(readers);
}
}
}
///
/// constructor that takes in a list of XmlReaders and creates metadata for mapping
/// in all the files.
///
/// The edm metadata collection that this mapping is to use
/// The store metadata collection that this mapping is to use
/// The XmlReaders to load mapping from
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm")]
public StorageMappingItemCollection(EdmItemCollection edmCollection,
StoreItemCollection storeCollection,
IEnumerable xmlReaders)
: base(DataSpace.CSSpace)
{
EntityUtil.CheckArgumentNull(xmlReaders, "xmlReaders");
MetadataArtifactLoader composite = MetadataArtifactLoader.CreateCompositeFromXmlReaders(xmlReaders);
this.Init(edmCollection,
storeCollection,
composite.GetReaders(), // filter out duplicates
composite.GetPaths(),
true /* throwOnError*/);
}
///
/// constructor that takes in a list of XmlReaders and creates metadata for mapping
/// in all the files.
///
/// The edm metadata collection that this mapping is to use
/// The store metadata collection that this mapping is to use
/// Mapping URIs
/// The XmlReaders to load mapping from
/// a list of errors for each file loaded
// referenced by System.Data.Entity.Design.dll
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
internal StorageMappingItemCollection(EdmItemCollection edmCollection,
StoreItemCollection storeCollection,
IEnumerable xmlReaders,
List filePaths,
out IList errors)
: base(DataSpace.CSSpace)
{
// we will check the parameters for this internal ctor becuase
// it is pretty much publicly exposed through the MetadataItemCollectionFactory
// in System.Data.Entity.Design
EntityUtil.CheckArgumentNull(xmlReaders, "xmlReaders");
EntityUtil.CheckArgumentContainsNull(ref xmlReaders, "xmlReaders");
// filePaths is allowed to be null
errors = this.Init(edmCollection, storeCollection, xmlReaders, filePaths, false /*throwOnError*/);
}
///
/// constructor that takes in a list of XmlReaders and creates metadata for mapping
/// in all the files.
///
/// The edm metadata collection that this mapping is to use
/// The store metadata collection that this mapping is to use
/// Mapping URIs
/// The XmlReaders to load mapping from
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
internal StorageMappingItemCollection(EdmItemCollection edmCollection,
StoreItemCollection storeCollection,
IEnumerable xmlReaders,
List filePaths)
: base(DataSpace.CSSpace)
{
this.Init(edmCollection, storeCollection, xmlReaders, filePaths, true /*throwOnError*/);
}
///
/// Initializer that takes in a list of XmlReaders and creates metadata for mapping
/// in all the files.
///
/// The edm metadata collection that this mapping is to use
/// The store metadata collection that this mapping is to use
/// Mapping URIs
/// The XmlReaders to load mapping from
/// a list of errors for each file loaded
private IList Init(EdmItemCollection edmCollection,
StoreItemCollection storeCollection,
IEnumerable xmlReaders,
List filePaths,
bool throwOnError)
{
EntityUtil.CheckArgumentNull(xmlReaders, "xmlReaders");
EntityUtil.CheckArgumentNull(edmCollection, "edmCollection");
EntityUtil.CheckArgumentNull(storeCollection, "storeCollection");
this.m_edmCollection = edmCollection;
this.m_storeItemCollection = storeCollection;
Dictionary userDefinedQueryViewsDict;
Dictionary userDefinedQueryViewsOfTypeDict;
this.m_viewDictionary = new ViewDictionary(this, out userDefinedQueryViewsDict, out userDefinedQueryViewsOfTypeDict);
List errors = new List();
if(this.m_edmCollection.EdmVersion != XmlConstants.UndefinedVersion &&
this.m_storeItemCollection.SchemaVersion != XmlConstants.UndefinedVersion &&
this.m_edmCollection.EdmVersion != this.m_storeItemCollection.SchemaVersion)
{
errors.Add(
new EdmSchemaError(
Strings.Mapping_DifferentEdmStoreVersion,
(int)StorageMappingErrorCode.MappingDifferentEdmStoreVersion, EdmSchemaErrorSeverity.Error));
}
else
{
double expectedVersion = this.m_edmCollection.EdmVersion != XmlConstants.UndefinedVersion
? this.m_edmCollection.EdmVersion
: this.m_storeItemCollection.SchemaVersion;
errors.AddRange(LoadItems(xmlReaders, filePaths, userDefinedQueryViewsDict, userDefinedQueryViewsOfTypeDict, expectedVersion));
}
Debug.Assert(errors != null);
if (throwOnError && errors.Count != 0)
{
if (!System.Data.Common.Utils.MetadataHelper.CheckIfAllErrorsAreWarnings(errors))
{
// NOTE: not using Strings.InvalidSchemaEncountered because it will truncate the errors list.
throw new MappingException(
String.Format(System.Globalization.CultureInfo.CurrentCulture,
EntityRes.GetString(EntityRes.InvalidSchemaEncountered),
Helper.CombineErrorMessage(errors)));
}
}
return errors;
}
#endregion Constructors
///
/// Return the EdmItemCollection associated with the Mapping Collection
///
internal EdmItemCollection EdmItemCollection
{
get
{
return this.m_edmCollection;
}
}
internal double MappingVersion
{
get
{
return this.m_mappingVersion;
}
}
///
/// Return the StoreItemCollection associated with the Mapping Collection
///
internal StoreItemCollection StoreItemCollection
{
get
{
return this.m_storeItemCollection;
}
}
///
/// Search for a Mapping metadata with the specified type key.
///
/// identity of the type
/// The dataspace that the type for which map needs to be returned belongs to
/// true for case-insensitive lookup
/// Thrown if mapping space is not valid
internal override Map GetMap(string identity, DataSpace typeSpace, bool ignoreCase)
{
EntityUtil.CheckArgumentNull(identity, "identity");
if (typeSpace != DataSpace.CSpace)
{
throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.Mapping_Storage_InvalidSpace_1(typeSpace));
}
return GetItem