|
//---------------------------------------------------------------------
// <copyright file="StorageSetMapping.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//
// @owner Microsoft
// @backupOwner Microsoft
//---------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Data.Metadata.Edm;
using System.Data.Common.Utils;
using System.Diagnostics;
using System.Linq;
namespace System.Data.Mapping {
using Triple = Pair<EntitySetBase, Pair<EntityTypeBase, bool>>;
/// <summary>
/// Represents the Mapping metadata for an Extent in CS space.
/// </summary>
/// <example>
/// For Example if conceptually you could represent the CS MSL file as following
/// --Mapping
/// --EntityContainerMapping ( CNorthwind-->SNorthwind )
/// --EntitySetMapping
/// --EntityTypeMapping
/// --MappingFragment
/// --EntityTypeMapping
/// --MappingFragment
/// --AssociationSetMapping
/// --AssociationTypeMapping
/// --MappingFragment
/// This class represents the metadata for all the extent map elements in the
/// above example namely EntitySetMapping, AssociationSetMapping and CompositionSetMapping.
/// The SetMapping elements that are children of the EntityContainerMapping element
/// can be accessed through the properties on this type.
/// </example>
internal abstract class StorageSetMapping
{
#region Constructors
/// <summary>
/// Construct the new StorageSetMapping object.
/// </summary>
/// <param name="extent">Extent metadata object</param>
/// <param name="entityContainerMapping">The EntityContainer mapping that contains this extent mapping</param>
internal StorageSetMapping(EntitySetBase extent, StorageEntityContainerMapping entityContainerMapping) {
this.m_entityContainerMapping = entityContainerMapping;
this.m_extent = extent;
this.m_typeMappings = new List<StorageTypeMapping>();
}
#endregion
#region Fields
/// <summary>
/// The EntityContainer mapping that contains this extent mapping.
/// </summary>
private StorageEntityContainerMapping m_entityContainerMapping;
/// <summary>
/// The extent for which this mapping represents.
/// </summary>
private EntitySetBase m_extent;
/// <summary>
/// Set of type mappings that make up the Set Mapping.
/// Unless this is a EntitySetMapping with inheritance,
/// you would have a single type mapping per set.
/// </summary>
private List<StorageTypeMapping> m_typeMappings;
/// <summary>
/// User defined Query View for the EntitySet.
/// </summary>
private string m_queryView;
/// <summary>
/// Line Number for Set Mapping element start tag.
/// </summary>
private int m_startLineNumber;
/// <summary>
/// Line position for Set Mapping element start tag.
/// </summary>
private int m_startLinePosition;
/// <summary>
/// Has modificationfunctionmapping for set mapping.
/// </summary>
private bool m_hasModificationFunctionMapping;
/// <summary>
/// Stores type-Specific user-defined QueryViews.
/// </summary>
private Dictionary<Triple, string> m_typeSpecificQueryViews = new Dictionary<Triple, string>(Triple.PairComparer.Instance);
#endregion
#region Properties
/// <summary>
/// The set for which this mapping is for
/// </summary>
internal EntitySetBase Set
{
get {
return this.m_extent;
}
}
///// <summary>
///// TypeMappings that make up this set type.
///// For AssociationSet and CompositionSet there will be one type (at least that's what
///// we expect as of now). EntitySet could have mappings for multiple Entity types.
///// </summary>
internal ReadOnlyCollection<StorageTypeMapping> TypeMappings
{
get
{
return this.m_typeMappings.AsReadOnly();
}
}
internal StorageEntityContainerMapping EntityContainerMapping
{
get
{
return m_entityContainerMapping;
}
}
/// <summary>
/// Whether the SetMapping has empty content
/// Returns true if there no table Mapping fragments
/// </summary>
internal virtual bool HasNoContent
{
get
{
if (QueryView != null)
{
return false;
}
foreach (StorageTypeMapping typeMap in TypeMappings)
{
foreach (StorageMappingFragment mapFragment in typeMap.MappingFragments)
{
foreach (StoragePropertyMapping propertyMap in mapFragment.AllProperties)
{
return false;
}
}
}
return true;
}
}
internal string QueryView
{
get { return m_queryView; }
set { m_queryView = value; }
}
/// <summary>
/// Line Number in MSL file where the Set Mapping Element's Start Tag is present.
/// </summary>
internal int StartLineNumber
{
get
{
return m_startLineNumber;
}
set
{
m_startLineNumber = value;
}
}
/// <summary>
/// Line Position in MSL file where the Set Mapping Element's Start Tag is present.
/// </summary>
internal int StartLinePosition
{
get
{
return m_startLinePosition;
}
set
{
m_startLinePosition = value;
}
}
internal bool HasModificationFunctionMapping
{
get
{
return m_hasModificationFunctionMapping;
}
set
{
m_hasModificationFunctionMapping = value;
}
}
#endregion
#region Methods
/// <summary>
/// Add type mapping as a child under this SetMapping
/// </summary>
/// <param name="typeMapping"></param>
internal void AddTypeMapping(StorageTypeMapping typeMapping)
{
this.m_typeMappings.Add(typeMapping);
}
/// <summary>
/// This method is primarily for debugging purposes.
/// Will be removed shortly.
/// </summary>
internal abstract void Print(int index);
internal bool ContainsTypeSpecificQueryView(Triple key)
{
return m_typeSpecificQueryViews.ContainsKey(key);
}
/// <summary>
/// Stores a type-specific user-defiend QueryView so that it can be loaded
/// into StorageMappingItemCollection's view cache.
/// </summary>
internal void AddTypeSpecificQueryView(Triple key, string viewString)
{
Debug.Assert(!m_typeSpecificQueryViews.ContainsKey(key), "Query View already present for the given Key");
m_typeSpecificQueryViews.Add(key, viewString);
}
internal ReadOnlyCollection<Triple> GetTypeSpecificQVKeys()
{
return new ReadOnlyCollection<Triple>(m_typeSpecificQueryViews.Keys.ToList());
}
internal string GetTypeSpecificQueryView(Triple key)
{
Debug.Assert(m_typeSpecificQueryViews.ContainsKey(key));
return m_typeSpecificQueryViews[key];
}
#endregion
}
}
|