e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
183 lines
6.2 KiB
C#
183 lines
6.2 KiB
C#
//---------------------------------------------------------------------
|
|
// <copyright file="EntityContainerAssociationSetEnd.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
//
|
|
// @owner [....]
|
|
// @backupOwner [....]
|
|
//---------------------------------------------------------------------
|
|
|
|
namespace System.Data.EntityModel.SchemaObjectModel
|
|
{
|
|
using System.Collections.Generic;
|
|
using System.Data.Metadata.Edm;
|
|
using System.Diagnostics;
|
|
using System.Xml;
|
|
|
|
/// <summary>
|
|
/// Represents an element.
|
|
/// </summary>
|
|
internal sealed class EntityContainerAssociationSetEnd : EntityContainerRelationshipSetEnd
|
|
{
|
|
private string _unresolvedRelationshipEndRole;
|
|
|
|
/// <summary>
|
|
/// Constructs an EntityContainerAssociationSetEnd
|
|
/// </summary>
|
|
/// <param name="parentElement">Reference to the schema element.</param>
|
|
public EntityContainerAssociationSetEnd( EntityContainerAssociationSet parentElement )
|
|
: base( parentElement )
|
|
{
|
|
}
|
|
|
|
public string Role
|
|
{
|
|
get
|
|
{
|
|
return _unresolvedRelationshipEndRole;
|
|
}
|
|
set
|
|
{
|
|
_unresolvedRelationshipEndRole = value;
|
|
}
|
|
}
|
|
|
|
public override string Name
|
|
{
|
|
get
|
|
{
|
|
return Role;
|
|
}
|
|
}
|
|
|
|
protected override bool HandleAttribute(XmlReader reader)
|
|
{
|
|
if (base.HandleAttribute(reader))
|
|
{
|
|
return true;
|
|
}
|
|
else if (CanHandleAttribute(reader, XmlConstants.Role))
|
|
{
|
|
HandleRoleAttribute(reader);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// This is the method that is called when an Role Attribute is encountered.
|
|
/// </summary>
|
|
/// <param name="reader">The XmlRead positned at the extent attribute.</param>
|
|
private void HandleRoleAttribute( XmlReader reader )
|
|
{
|
|
_unresolvedRelationshipEndRole = HandleUndottedNameAttribute( reader, _unresolvedRelationshipEndRole );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Used during the resolve phase to resolve the type name to the object that represents that type
|
|
/// </summary>
|
|
internal override void ResolveTopLevelNames()
|
|
{
|
|
base.ResolveTopLevelNames();
|
|
|
|
// resolve end name to the corosponding relationship end
|
|
IRelationship relationship = ParentElement.Relationship;
|
|
if ( relationship == null )
|
|
{
|
|
// error already logged for this
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
internal override void ResolveSecondLevelNames()
|
|
{
|
|
base.ResolveSecondLevelNames();
|
|
|
|
if (_unresolvedRelationshipEndRole == null && EntitySet != null)
|
|
{
|
|
// no role provided, infer it
|
|
RelationshipEnd = InferRelationshipEnd(EntitySet);
|
|
if (RelationshipEnd != null)
|
|
{
|
|
_unresolvedRelationshipEndRole = RelationshipEnd.Name;
|
|
}
|
|
}
|
|
else if (_unresolvedRelationshipEndRole != null)
|
|
{
|
|
IRelationship relationship = ParentElement.Relationship;
|
|
IRelationshipEnd end;
|
|
if (relationship.TryGetEnd(_unresolvedRelationshipEndRole, out end))
|
|
{
|
|
RelationshipEnd = end;
|
|
}
|
|
else
|
|
{
|
|
// couldn't find a matching relationship end for this RelationshipSet end
|
|
AddError(ErrorCode.InvalidContainerTypeForEnd, EdmSchemaErrorSeverity.Error,
|
|
System.Data.Entity.Strings.InvalidEntityEndName(Role, relationship.FQName));
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// If the role name is missing but an entity set is given, figure out what the
|
|
/// relationship end should be
|
|
/// </summary>
|
|
/// <param name="set">The given EntitySet</param>
|
|
/// <returns>The appropriate relationship end</returns>
|
|
private IRelationshipEnd InferRelationshipEnd( EntityContainerEntitySet set )
|
|
{
|
|
Debug.Assert(set != null, "set parameter is null");
|
|
|
|
if ( ParentElement.Relationship == null )
|
|
{
|
|
return null;
|
|
}
|
|
|
|
List<IRelationshipEnd> possibleEnds = new List<IRelationshipEnd>();
|
|
foreach ( IRelationshipEnd end in ParentElement.Relationship.Ends )
|
|
{
|
|
if ( set.EntityType.IsOfType( end.Type ) )
|
|
{
|
|
possibleEnds.Add( end );
|
|
}
|
|
}
|
|
|
|
if ( possibleEnds.Count == 1 )
|
|
{
|
|
return possibleEnds[0];
|
|
}
|
|
else if ( possibleEnds.Count == 0 )
|
|
{
|
|
// no matchs
|
|
AddError( ErrorCode.FailedInference, EdmSchemaErrorSeverity.Error,
|
|
System.Data.Entity.Strings.InferRelationshipEndFailedNoEntitySetMatch(
|
|
set.Name, this.ParentElement.Name, ParentElement.Relationship.FQName, set.EntityType.FQName, this.ParentElement.ParentElement.FQName ) );
|
|
}
|
|
else
|
|
{
|
|
// ambiguous
|
|
AddError( ErrorCode.FailedInference, EdmSchemaErrorSeverity.Error,
|
|
System.Data.Entity.Strings.InferRelationshipEndAmbiguous(
|
|
set.Name, this.ParentElement.Name, ParentElement.Relationship.FQName, set.EntityType.FQName, this.ParentElement.ParentElement.FQName));
|
|
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
internal override SchemaElement Clone(SchemaElement parentElement)
|
|
{
|
|
EntityContainerAssociationSetEnd setEnd = new EntityContainerAssociationSetEnd((EntityContainerAssociationSet)parentElement);
|
|
setEnd._unresolvedRelationshipEndRole = _unresolvedRelationshipEndRole;
|
|
setEnd.EntitySet = this.EntitySet;
|
|
|
|
return setEnd;
|
|
}
|
|
|
|
}
|
|
}
|