Skip to content

Commit

Permalink
Added support for generating many to many relations in mermaid-er-dia…
Browse files Browse the repository at this point in the history
…gram-from-efcore (#133)
  • Loading branch information
ebjornset authored Nov 2, 2024
1 parent a0fd97e commit d861547
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 9 deletions.
3 changes: 2 additions & 1 deletion docs/templates/releasenotes/yyyy-MM-dd-v-x.y.z.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
### Improvements in this version
## Prerelease 2
- Added support for generating many to many association in `mermaid-class-diagram-from-csharp`.
- Added support for generating many to many associations in `mermaid-class-diagram-from-csharp`.
- Added support for generating many to many relations in `mermaid-er-diagram-from-csharp`.
## Prerelease 1 (2024-10-29)
- Fixed an issue where `mermaid-er-diagram-from-efcore` would fail when an input assebly referenced Asp.Net Core.
- Ie the .csproj file contained `<Project Sdk="Microsoft.NET.Sdk.Web">` or `<FrameworkReference Include="Microsoft.AspNetCore.App|All">` or referenced such an assembly.
Expand Down
28 changes: 26 additions & 2 deletions src/DryGen.MermaidFromCSharp/ErDiagram/ErDiagramEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,13 @@ public void AddAttribute(ErDiagramAttribute attribute)

public void AddRelationship(ErDiagramEntity to, ErDiagramRelationshipCardinality fromCardinality, ErDiagramRelationshipCardinality toCardinality, string label, string propertyName, bool isIdentifying = false)
{
var relationShip = new ErDiagramRelationship(to, fromCardinality, toCardinality, label, propertyName, isIdentifying);
relationships.Add(relationShip);
var relationship = new ErDiagramRelationship(to, fromCardinality, toCardinality, label, propertyName, isIdentifying);
relationships.Add(relationship);
}

public void RemoveRelationship(ErDiagramRelationship relationship)
{
relationships.Remove(relationship);
}

public void RemoveBidirectionalRelationshipDuplicates()
Expand All @@ -47,6 +52,25 @@ public void RemoveBidirectionalRelationshipDuplicates()
|| r.To.GetRelationships().Any(x => x.To == this)));
}

public void MergeTwoOneToManyIntoOneMayToMany()
{
bool wasModified;
do
{
// Must use an outer loop since a self referencing many to many will modify the relationships collection and the enumeration will crash
wasModified = false;
foreach (var relationship in relationships.Where(x => x.FromCardinality == ErDiagramRelationshipCardinality.ExactlyOne && x.ToCardinality == ErDiagramRelationshipCardinality.ZeroOrMore && ! x.IsIdenifying)) {
var backRelationship = relationship.To.Relationships.FirstOrDefault(x => x.To == this && x.FromCardinality == ErDiagramRelationshipCardinality.ExactlyOne && x.ToCardinality == ErDiagramRelationshipCardinality.ZeroOrMore && ! x.IsIdenifying && x != relationship);
if (backRelationship == null) {
continue;
}
relationship.MergeAsManyToManyWith(backRelationship);
wasModified = true;
break;
}
} while (wasModified);
}

protected override bool IsRelatedTo(IDiagramType type)
{
var result = relationships.Exists(x => x.To.Type == type.Type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@ public ErDiagramRelationship(
}

public ErDiagramEntity To { get; }
public ErDiagramRelationshipCardinality FromCardinality { get; }
public ErDiagramRelationshipCardinality FromCardinality { get; private set; }
public ErDiagramRelationshipCardinality ToCardinality { get; }
public string Label { get; }
internal string PropertyName { get; }
public bool IsIdenifying { get; }

public void MergeAsManyToManyWith(ErDiagramRelationship backRelationship) {
FromCardinality = ErDiagramRelationshipCardinality.ZeroOrMore;
To.RemoveRelationship(backRelationship);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ private static void GeneratieErStructure(IList<ErDiagramEntity> entities, IReadO
var genericArgumentPropertyType = propertyType.GetGenericArguments()[0];
if (entityLookup.TryGetValue(genericArgumentPropertyType, out var toEntity))
{
entity.AddRelationship(toEntity, ErDiagramRelationshipCardinality.ExactlyOne, ErDiagramRelationshipCardinality.ZeroOrMore, string.Empty, property.Name);
var label = property.Name.Contains(toEntity.Name) ? string.Empty : property.Name.ToNormalizedRelationshipLabel();
entity.AddRelationship(toEntity, ErDiagramRelationshipCardinality.ExactlyOne, ErDiagramRelationshipCardinality.ZeroOrMore, label, property.Name);
}
}
else if (property.IsErDiagramAttributePropertyType())
Expand All @@ -56,6 +57,10 @@ private static void GeneratieErStructure(IList<ErDiagramEntity> entities, IReadO
{
entity.RemoveBidirectionalRelationshipDuplicates();
}
foreach (var entity in entities)
{
entity.MergeTwoOneToManyIntoOneMayToMany();
}
enumEntities.AppendToEntities(entities);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ Scenario: Generates many to many relationship with only one property in the key
"""
Examples:
| Structure builder |
#| Reflection |
| Reflection |
| EfCore |

Scenario: Generates many to many relationship with several properties in the key
Expand Down Expand Up @@ -412,7 +412,7 @@ Scenario: Generates many to many relationship with several properties in the key
"""
Examples:
| Structure builder |
#| Reflection |
| Reflection |
| EfCore |

Scenario: Generates self referencing many to many relationship with only one property in the key
Expand Down Expand Up @@ -444,7 +444,7 @@ Scenario: Generates self referencing many to many relationship with only one pro
"""
Examples:
| Structure builder |
#| Reflection |
| Reflection |
| EfCore |

Scenario: Generates self referencing many to many relationship with several properties in the key
Expand Down Expand Up @@ -482,5 +482,5 @@ Scenario: Generates self referencing many to many relationship with several prop
"""
Examples:
| Structure builder |
#| Reflection |
| Reflection |
| EfCore |

0 comments on commit d861547

Please sign in to comment.