in src/Core/Resolvers/MultipleCreateOrderHelper.cs [45:126]
public static string GetReferencingEntityName(
IMiddlewareContext context,
string relationshipName,
string sourceEntityName,
string targetEntityName,
ISqlMetadataProvider metadataProvider,
Dictionary<string, IValueNode?> columnDataInSourceBody,
IValueNode? targetNodeValue,
int nestingLevel,
bool isMNRelationship = false)
{
if (!metadataProvider.GetEntityNamesAndDbObjects().TryGetValue(sourceEntityName, out DatabaseObject? sourceDbObject) ||
!metadataProvider.GetEntityNamesAndDbObjects().TryGetValue(targetEntityName, out DatabaseObject? targetDbObject))
{
// This should not be hit ideally.
throw new DataApiBuilderException(
message: $"Could not determine definition for source: {sourceEntityName} and target: {targetEntityName} entities for " +
$"relationship: {relationshipName} at level: {nestingLevel}",
statusCode: HttpStatusCode.InternalServerError,
subStatusCode: DataApiBuilderException.SubStatusCodes.EntityNotFound);
}
if (sourceDbObject.GetType() != typeof(DatabaseTable) || targetDbObject.GetType() != typeof(DatabaseTable))
{
throw new DataApiBuilderException(
message: $"Cannot execute multiple-create for relationship: {relationshipName} at level: {nestingLevel} because currently DAB supports" +
$"multiple-create only for entities backed by tables.",
statusCode: HttpStatusCode.BadRequest,
subStatusCode: DataApiBuilderException.SubStatusCodes.NotSupported);
}
DatabaseTable sourceDbTable = (DatabaseTable)sourceDbObject;
DatabaseTable targetDbTable = (DatabaseTable)targetDbObject;
if (sourceDbTable.Equals(targetDbTable))
{
// DAB does not yet support multiple-create for self referencing relationships where both the source and
// target entities are backed by same database table.
throw new DataApiBuilderException(
message: $"Multiple-create for relationship: {relationshipName} at level: {nestingLevel} is not supported because the " +
$"source entity: {sourceEntityName} and the target entity: {targetEntityName} are backed by the same database table.",
statusCode: HttpStatusCode.BadRequest,
subStatusCode: DataApiBuilderException.SubStatusCodes.NotSupported);
}
if (isMNRelationship)
{
// For M:N relationships, neither the source nor the target entity act as the referencing entity.
// Instead, the linking table act as the referencing entity.
return string.Empty;
}
if (TryDetermineReferencingEntityBasedOnEntityRelationshipMetadata(
sourceEntityName: sourceEntityName,
targetEntityName: targetEntityName,
sourceDbTable: sourceDbTable,
referencingEntityName: out string? referencingEntityNameBasedOnEntityMetadata))
{
return referencingEntityNameBasedOnEntityMetadata;
}
else
{
// Had the target node represented an array value, it would have been an 1:N relationship from (source, target).
// For that case, we would not hit this code because the entity metadata would have been sufficient to tell us that the target entity
// is the referencing entity. Hence we conclude that the target node must represent a single input object corresponding to N:1 or 1:1 relationship types.
ObjectValueNode? objectValueNode = (ObjectValueNode?)targetNodeValue;
Dictionary<string, IValueNode?> columnDataInTargetBody = GetBackingColumnDataFromFields(
context: context,
entityName: targetEntityName,
fieldNodes: objectValueNode!.Fields,
metadataProvider: metadataProvider);
return DetermineReferencingEntityBasedOnRequestBody(
relationshipName: relationshipName,
sourceEntityName: sourceEntityName,
targetEntityName: targetEntityName,
sourceDbObject: sourceDbObject,
targetDbObject: targetDbObject,
columnDataInSourceBody: columnDataInSourceBody,
columnDataInTargetBody: columnDataInTargetBody,
nestingLevel: nestingLevel);
}
}