public override string GetToolTipText(DiagramItem item) { UnidirectionalAssociation association = item.Shape.ModelElement as UnidirectionalAssociation; return(association != null ? $"{association.Source.Name}.{association.TargetPropertyName}" : string.Empty); }
private void ProcessUnidirectionalAssociations(ParsingModels.ModelClass modelClass) { List<ModelUnidirectionalAssociation> unidirectionalAssociations = modelClass.UnidirectionalAssociations; foreach (ModelUnidirectionalAssociation data in unidirectionalAssociations) { if (Store.ModelRoot().EntityFrameworkVersion == EFVersion.EF6 && data.SourceMultiplicity != ParsingModels.Multiplicity.ZeroMany && data.TargetMultiplicity != ParsingModels.Multiplicity.ZeroMany) { data.ForeignKey = null; } UnidirectionalAssociation existing = Store.GetAll<UnidirectionalAssociation>() .FirstOrDefault(x => x.Target.Name == data.TargetClassName && x.Source.Name == data.SourceClassName && x.Source.Name == modelClass.Name // just to be sure && x.TargetPropertyName == data.TargetPropertyName); if (existing != null) { if (string.IsNullOrWhiteSpace(existing.FKPropertyName) && !string.IsNullOrWhiteSpace(data.ForeignKey)) { existing.FKPropertyName = data.ForeignKey; existing.Source.ModelRoot.ExposeForeignKeys = true; } continue; } ModelClass source = Store.GetAll<ModelClass>().FirstOrDefault(c => c.FullName == data.SourceClassFullName); ModelClass target = Store.GetAll<ModelClass>().FirstOrDefault(c => c.FullName == data.TargetClassFullName); if (source == null || target == null || source.FullName != modelClass.FullName) continue; // ReSharper disable once UnusedVariable UnidirectionalAssociation element = new UnidirectionalAssociation(Store, new[] { new RoleAssignment(UnidirectionalAssociation.UnidirectionalSourceDomainRoleId, source), new RoleAssignment(UnidirectionalAssociation.UnidirectionalTargetDomainRoleId, target) }, new[] { new PropertyAssignment(Association.SourceMultiplicityDomainPropertyId, ConvertMultiplicity(data.SourceMultiplicity)), new PropertyAssignment(Association.TargetMultiplicityDomainPropertyId, ConvertMultiplicity(data.TargetMultiplicity)), new PropertyAssignment(Association.TargetPropertyNameDomainPropertyId, data.TargetPropertyName), new PropertyAssignment(Association.TargetSummaryDomainPropertyId, data.TargetSummary), new PropertyAssignment(Association.TargetDescriptionDomainPropertyId, data.TargetDescription), new PropertyAssignment(Association.FKPropertyNameDomainPropertyId, data.ForeignKey), new PropertyAssignment(Association.SourceRoleDomainPropertyId, ConvertRole(data.SourceRole)), new PropertyAssignment(Association.TargetRoleDomainPropertyId, ConvertRole(data.TargetRole)), }); AssociationChangedRules.SetEndpointRoles(element); } }
public static NavigationProperty LinkToSource(UnidirectionalAssociation association) { return(new NavigationProperty { Cardinality = association.SourceMultiplicity , ClassType = association.Source , AssociationObject = association , FKPropertyName = association.SourceRole == EndpointRole.Principal ? association.FKPropertyName : null , PointsToSource = true }); }
private static ElementLink ConnectModelClassToModelClass(ModelClass sourceAccepted, ModelClass targetAccepted) { ElementLink result = new UnidirectionalAssociation(sourceAccepted, targetAccepted); if (DomainClassInfo.HasNameProperty(result)) { DomainClassInfo.SetUniqueName(result); } return(result); }
public override void ElementAdded(ElementAddedEventArgs e) { base.ElementAdded(e); UnidirectionalAssociation element = (UnidirectionalAssociation)e.ModelElement; Store store = element.Store; Transaction current = store.TransactionManager.CurrentTransaction; if (current.IsSerializing || ModelRoot.BatchUpdating) { return; } PresentationHelper.UpdateAssociationDisplay(element); }
private void ProcessUnidirectionalAssociations(List<ModelUnidirectionalAssociation> unidirectionalAssociations) { foreach (ModelUnidirectionalAssociation data in unidirectionalAssociations) { if (Store.Get<UnidirectionalAssociation>() .Any(x => x.Target.FullName == data.TargetClassFullName && x.Source.FullName == data.SourceClassFullName && x.TargetPropertyName == data.TargetPropertyName)) continue; ModelClass source = Store.Get<ModelClass>().FirstOrDefault(c => c.FullName == data.SourceClassFullName); if (source == null) continue; ModelClass target = Store.Get<ModelClass>().FirstOrDefault(c => c.FullName == data.TargetClassFullName); if (target == null) continue; // ReSharper disable once UnusedVariable UnidirectionalAssociation element = new UnidirectionalAssociation(Store, new[] { new RoleAssignment(UnidirectionalAssociation.UnidirectionalSourceDomainRoleId, source), new RoleAssignment(UnidirectionalAssociation.UnidirectionalTargetDomainRoleId, target) }, new[] { new PropertyAssignment(Association.SourceMultiplicityDomainPropertyId, ConvertMultiplicity(data.SourceMultiplicity)), new PropertyAssignment(Association.TargetMultiplicityDomainPropertyId, ConvertMultiplicity(data.TargetMultiplicity)), new PropertyAssignment(Association.TargetPropertyNameDomainPropertyId, data.TargetPropertyName), new PropertyAssignment(Association.TargetSummaryDomainPropertyId, data.TargetSummary), new PropertyAssignment(Association.TargetDescriptionDomainPropertyId, data.TargetDescription) }); } }
protected override void WriteTargetDeleteBehavior(UnidirectionalAssociation association, List <string> segments) { if (!association.Source.IsDependentType && !association.Target.IsDependentType && (association.TargetRole == EndpointRole.Principal || association.SourceRole == EndpointRole.Principal)) { DeleteAction deleteAction = association.SourceRole == EndpointRole.Principal ? association.SourceDeleteAction : association.TargetDeleteAction; switch (deleteAction) { case DeleteAction.None: segments.Add("OnDelete(DeleteBehavior.NoAction)"); break; case DeleteAction.Cascade: segments.Add("OnDelete(DeleteBehavior.Cascade)"); break; } } }
void WriteConstructor(ModelClass modelClass) { Output("partial void Init();"); NL(); /***********************************************************************/ // Default constructor /***********************************************************************/ bool hasRequiredParameters = GetRequiredParameters(modelClass, false).Any(); bool hasOneToOneAssociations = modelClass.AllRequiredNavigationProperties() .Any(np => np.AssociationObject.SourceMultiplicity == Sawczyn.EFDesigner.EFModel.Multiplicity.One && np.AssociationObject.TargetMultiplicity != Sawczyn.EFDesigner.EFModel.Multiplicity.One); string visibility = (hasRequiredParameters || modelClass.IsAbstract) && !modelClass.IsDependentType ? "protected" : "public"; if (visibility == "public") { Output("/// <summary>"); Output("/// Default constructor"); Output("/// </summary>"); } else if (modelClass.IsAbstract) { Output("/// <summary>"); Output("/// Default constructor. Protected due to being abstract."); Output("/// </summary>"); } else if (hasRequiredParameters) { Output("/// <summary>"); Output("/// Default constructor. Protected due to required properties, but present because EF needs it."); Output("/// </summary>"); } List<string> remarks = new List<string>(); if (hasOneToOneAssociations) { List<Association> oneToOneAssociations = modelClass.AllRequiredNavigationProperties() .Where(np => np.AssociationObject.SourceMultiplicity == Sawczyn.EFDesigner.EFModel.Multiplicity.One && np.AssociationObject.TargetMultiplicity == Sawczyn.EFDesigner.EFModel.Multiplicity.One) .Select(np => np.AssociationObject) .ToList(); List<ModelClass> otherEndsOneToOne = oneToOneAssociations.Where(a => a.Source != modelClass).Select(a => a.Target) .Union(oneToOneAssociations.Where(a => a.Target != modelClass).Select(a => a.Source)) .ToList(); if (oneToOneAssociations.Any(a => a.Source.Name == modelClass.Name && a.Target.Name == modelClass.Name)) otherEndsOneToOne.Add(modelClass); if (otherEndsOneToOne.Any()) { string nameList = otherEndsOneToOne.Count == 1 ? otherEndsOneToOne.First().Name : string.Join(", ", otherEndsOneToOne.Take(otherEndsOneToOne.Count - 1).Select(c => c.Name)) + " and " + (otherEndsOneToOne.Last().Name != modelClass.Name ? otherEndsOneToOne.Last().Name : "itself"); remarks.Add($"// NOTE: This class has one-to-one associations with {nameList}."); remarks.Add("// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other."); } } Output(modelClass.Superclass != null ? $"{visibility} {modelClass.Name}(): base()" : $"{visibility} {modelClass.Name}()"); Output("{"); if (remarks.Count > 0) { foreach (string remark in remarks) Output(remark); NL(); } WriteDefaultConstructorBody(modelClass); Output("}"); NL(); if (visibility != "public" && !modelClass.IsAbstract) { Output("/// <summary>"); Output("/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving."); Output("/// </summary>"); Output($"public static {modelClass.Name} Create{modelClass.Name}Unsafe()"); Output("{"); Output($"return new {modelClass.Name}();"); Output("}"); NL(); } /***********************************************************************/ // Constructor with required parameters (if necessary) /***********************************************************************/ if (hasRequiredParameters) { visibility = modelClass.IsAbstract ? "protected" : "public"; Output("/// <summary>"); Output("/// Public constructor with required data"); Output("/// </summary>"); WriteConstructorComments(modelClass); Output($"{visibility} {modelClass.Name}({string.Join(", ", GetRequiredParameters(modelClass, null))})"); Output("{"); if (remarks.Count > 0) { foreach (string remark in remarks) Output(remark); NL(); } foreach (ModelAttribute requiredAttribute in modelClass.AllRequiredAttributes .Where(x => (!x.IsIdentity || x.IdentityType == IdentityType.Manual) && !x.IsConcurrencyToken && x.SetterVisibility == SetterAccessModifier.Public)) { if (requiredAttribute.Type == "String") Output($"if (string.IsNullOrEmpty({requiredAttribute.Name.ToLower()})) throw new ArgumentNullException(nameof({requiredAttribute.Name.ToLower()}));"); else if (requiredAttribute.Type.StartsWith("Geo")) Output($"if ({requiredAttribute.Name.ToLower()} == null) throw new ArgumentNullException(nameof({requiredAttribute.Name.ToLower()}));"); Output($"this.{requiredAttribute.Name} = {requiredAttribute.Name.ToLower()};"); NL(); } foreach (ModelAttribute modelAttribute in modelClass.Attributes.Where(x => x.SetterVisibility == SetterAccessModifier.Public && !x.Required && !string.IsNullOrEmpty(x.InitialValue) && x.InitialValue != "null")) { string quote = modelAttribute.Type == "String" ? "\"" : modelAttribute.Type == "Char" ? "'" : string.Empty; Output(quote.Length > 0 ? $"this.{modelAttribute.Name} = {quote}{FullyQualified(modelClass.ModelRoot, modelAttribute.InitialValue.Trim(quote[0]))}{quote};" : $"this.{modelAttribute.Name} = {quote}{FullyQualified(modelClass.ModelRoot, modelAttribute.InitialValue)}{quote};"); } foreach (NavigationProperty requiredNavigationProperty in modelClass.AllRequiredNavigationProperties() .Where(np => np.AssociationObject.SourceMultiplicity != Sawczyn.EFDesigner.EFModel.Multiplicity.One || np.AssociationObject.TargetMultiplicity != Sawczyn.EFDesigner.EFModel.Multiplicity.One)) { string parameterName = requiredNavigationProperty.PropertyName.ToLower(); Output($"if ({parameterName} == null) throw new ArgumentNullException(nameof({parameterName}));"); if (requiredNavigationProperty.IsCollection) Output($"{requiredNavigationProperty.PropertyName}.Add({parameterName});"); else if (requiredNavigationProperty.ConstructorParameterOnly) { UnidirectionalAssociation association = requiredNavigationProperty.AssociationObject as UnidirectionalAssociation; Output(association.TargetMultiplicity == Sawczyn.EFDesigner.EFModel.Multiplicity.ZeroMany ? $"{requiredNavigationProperty.PropertyName}.{association.TargetPropertyName}.Add(this);" : $"{requiredNavigationProperty.PropertyName}.{association.TargetPropertyName} = this;"); } else Output($"this.{requiredNavigationProperty.PropertyName} = {parameterName};"); NL(); } foreach (NavigationProperty navigationProperty in modelClass.LocalNavigationProperties() .Where(x => x.AssociationObject.Persistent && (x.IsCollection || x.ClassType.IsDependentType) && !x.ConstructorParameterOnly)) { if (!navigationProperty.IsCollection) Output($"this.{navigationProperty.PropertyName} = new {navigationProperty.ClassType.FullName}();"); else { string collectionType = GetFullContainerName(navigationProperty.AssociationObject.CollectionClass, navigationProperty.ClassType.FullName); Output($"this.{navigationProperty.PropertyName} = new {collectionType}();"); } } NL(); Output("Init();"); Output("}"); NL(); if (!modelClass.IsAbstract) { Output("/// <summary>"); Output("/// Static create function (for use in LINQ queries, etc.)"); Output("/// </summary>"); WriteConstructorComments(modelClass); string newToken = string.Empty; List<string> requiredParameters = GetRequiredParameters(modelClass, null); if (!AllSuperclassesAreNullOrAbstract(modelClass)) { List<string> superclassRequiredParameters = GetRequiredParameters(modelClass.Superclass, null); if (!requiredParameters.Except(superclassRequiredParameters).Any()) newToken = "new "; } Output($"public static {newToken}{modelClass.Name} Create({string.Join(", ", GetRequiredParameters(modelClass, null))})"); Output("{"); Output($"return new {modelClass.Name}({string.Join(", ", GetRequiredParameterNames(modelClass))});"); Output("}"); NL(); } } }
private void ProcessAssociation([NotNull] ModelClass source, [NotNull] ModelClass target, [NotNull] PropertyDeclarationSyntax propertyDecl, bool toMany = false) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (target == null) { throw new ArgumentNullException(nameof(target)); } if (propertyDecl == null) { throw new ArgumentNullException(nameof(propertyDecl)); } Transaction tx = Store.TransactionManager.CurrentTransaction == null ? Store.TransactionManager.BeginTransaction() : null; try { string propertyName = propertyDecl.Identifier.ToString(); // since we don't have enough information from the code, we'll create unidirectional associations // cardinality 1 on the source end, 0..1 or 0..* on the target, depending on the parameter XMLDocumentation xmlDocumentation = new XMLDocumentation(propertyDecl); // if the association doesn't yet exist, create it if (!Store.ElementDirectory .AllElements .OfType <UnidirectionalAssociation>() .Any(a => a.Source == source && a.Target == target && a.TargetPropertyName == propertyName)) { // if there's a unidirectional going the other direction, we'll whack that one and make a bidirectional // otherwise, proceed as planned UnidirectionalAssociation compliment = Store.ElementDirectory .AllElements .OfType <UnidirectionalAssociation>() .FirstOrDefault(a => a.Source == target && a.Target == source); if (compliment == null) { UnidirectionalAssociation _ = new UnidirectionalAssociation(Store, new[] { new RoleAssignment(UnidirectionalAssociation.UnidirectionalSourceDomainRoleId, source), new RoleAssignment(UnidirectionalAssociation.UnidirectionalTargetDomainRoleId, target) }, new[] { new PropertyAssignment(Association.SourceMultiplicityDomainPropertyId, Multiplicity.One), new PropertyAssignment(Association.TargetMultiplicityDomainPropertyId, toMany ? Multiplicity.ZeroMany : Multiplicity.ZeroOne), new PropertyAssignment(Association.TargetPropertyNameDomainPropertyId, propertyName), new PropertyAssignment(Association.TargetSummaryDomainPropertyId, xmlDocumentation.Summary), new PropertyAssignment(Association.TargetDescriptionDomainPropertyId, xmlDocumentation.Description) }); } else { compliment.Delete(); BidirectionalAssociation _ = new BidirectionalAssociation(Store, new[] { new RoleAssignment(BidirectionalAssociation.BidirectionalSourceDomainRoleId, source), new RoleAssignment(BidirectionalAssociation.BidirectionalTargetDomainRoleId, target) }, new[] { new PropertyAssignment(Association.SourceMultiplicityDomainPropertyId, compliment.TargetMultiplicity), new PropertyAssignment(BidirectionalAssociation.SourcePropertyNameDomainPropertyId, compliment.TargetPropertyName), new PropertyAssignment(BidirectionalAssociation.SourceSummaryDomainPropertyId, compliment.TargetSummary), new PropertyAssignment(BidirectionalAssociation.SourceDescriptionDomainPropertyId, compliment.TargetDescription), new PropertyAssignment(Association.TargetMultiplicityDomainPropertyId, toMany ? Multiplicity.ZeroMany : Multiplicity.ZeroOne), new PropertyAssignment(Association.TargetPropertyNameDomainPropertyId, propertyName), new PropertyAssignment(Association.TargetSummaryDomainPropertyId, xmlDocumentation.Summary), new PropertyAssignment(Association.TargetDescriptionDomainPropertyId, xmlDocumentation.Description) }); } } } catch { tx.Rollback(); tx = null; throw; } finally { tx?.Commit(); } }
private static void ProcessAssociation([NotNull] ModelClass source, [NotNull] ModelClass target, [NotNull] PropertyDeclarationSyntax propertyDecl, bool toMany = false) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (target == null) { throw new ArgumentNullException(nameof(target)); } if (propertyDecl == null) { throw new ArgumentNullException(nameof(propertyDecl)); } Store store = source.Store; Transaction tx = store.TransactionManager.CurrentTransaction == null ? store.TransactionManager.BeginTransaction() : null; try { string propertyName = propertyDecl.Identifier.ToString(); // since we don't have enough information from the code, we'll create unidirectional associations // cardinality 1 on the source end, 0..1 or 0..* on the target, depending on the parameter XMLDocumentation xmlDocumentation = new XMLDocumentation(propertyDecl); if (!store.ElementDirectory.AllElements.OfType <UnidirectionalAssociation>().Any(a => a.Source == source && a.Target == target && a.TargetPropertyName == propertyName)) { UnidirectionalAssociation unused = new UnidirectionalAssociation(store , new[] { new RoleAssignment(UnidirectionalAssociation.UnidirectionalSourceDomainRoleId, source) , new RoleAssignment(UnidirectionalAssociation.UnidirectionalTargetDomainRoleId, target) } , new[] { new PropertyAssignment(Association.SourceMultiplicityDomainPropertyId, Multiplicity.One) , new PropertyAssignment(Association.TargetMultiplicityDomainPropertyId , toMany ? Multiplicity.ZeroMany : Multiplicity.ZeroOne) , new PropertyAssignment(Association.TargetPropertyNameDomainPropertyId, propertyName) , new PropertyAssignment(Association.TargetSummaryDomainPropertyId, xmlDocumentation.Summary) , new PropertyAssignment(Association.TargetDescriptionDomainPropertyId, xmlDocumentation.Description) }); } } catch { tx = null; throw; } finally { tx?.Commit(); } }
private void ProcessUnidirectionalAssociations(ParsingModels.ModelClass modelClass) { List<ModelUnidirectionalAssociation> unidirectionalAssociations = modelClass.UnidirectionalAssociations; foreach (ModelUnidirectionalAssociation data in unidirectionalAssociations) { if (Store.ModelRoot().EntityFrameworkVersion == EFVersion.EF6 && data.SourceMultiplicity != ParsingModels.Multiplicity.ZeroMany && data.TargetMultiplicity != ParsingModels.Multiplicity.ZeroMany) { data.ForeignKey = null; } UnidirectionalAssociation existing = Store.GetAll<UnidirectionalAssociation>() .FirstOrDefault(x => x.Target.FullName == data.TargetClassFullName && x.Source.FullName == data.SourceClassFullName && x.Source.FullName == modelClass.FullName // just to be sure && x.TargetPropertyName == data.TargetPropertyName); if (existing != null) { if (string.IsNullOrWhiteSpace(existing.FKPropertyName) && !string.IsNullOrWhiteSpace(data.ForeignKey)) { existing.FKPropertyName = string.Join(",", data.ForeignKey.Split(',').ToList().Select(p => p.Split('/').Last().Split(' ').Last())); existing.Source.ModelRoot.ExposeForeignKeys = true; } continue; } ModelClass source = Store.GetAll<ModelClass>().FirstOrDefault(c => c.FullName == data.SourceClassFullName); ModelClass target = Store.GetAll<ModelClass>().FirstOrDefault(c => c.FullName == data.TargetClassFullName); if (source == null || target == null || source.FullName != modelClass.FullName) continue; UnidirectionalAssociation elementLink = (UnidirectionalAssociation)UnidirectionalAssociationBuilder.Connect(source, target); elementLink.SourceMultiplicity = ConvertMultiplicity(data.SourceMultiplicity); elementLink.TargetMultiplicity = ConvertMultiplicity(data.TargetMultiplicity); elementLink.TargetPropertyName = data.TargetPropertyName; elementLink.TargetSummary = data.TargetSummary; elementLink.TargetDescription = data.TargetDescription; elementLink.FKPropertyName = data.ForeignKey; elementLink.SourceRole = ConvertRole(data.SourceRole); elementLink.TargetRole = ConvertRole(data.TargetRole); //UnidirectionalAssociation element = new UnidirectionalAssociation(Store // , new[] // { // new RoleAssignment(UnidirectionalAssociation.UnidirectionalSourceDomainRoleId, source) // , new RoleAssignment(UnidirectionalAssociation.UnidirectionalTargetDomainRoleId, target) // } // , new[] // { // new PropertyAssignment(Association.SourceMultiplicityDomainPropertyId, ConvertMultiplicity(data.SourceMultiplicity)) // , new PropertyAssignment(Association.TargetMultiplicityDomainPropertyId, ConvertMultiplicity(data.TargetMultiplicity)) // , new PropertyAssignment(Association.TargetPropertyNameDomainPropertyId, data.TargetPropertyName) // , new PropertyAssignment(Association.TargetSummaryDomainPropertyId, data.TargetSummary) // , new PropertyAssignment(Association.TargetDescriptionDomainPropertyId, data.TargetDescription) // , new PropertyAssignment(Association.FKPropertyNameDomainPropertyId, data.ForeignKey) // , new PropertyAssignment(Association.SourceRoleDomainPropertyId, ConvertRole(data.SourceRole)) // , new PropertyAssignment(Association.TargetRoleDomainPropertyId, ConvertRole(data.TargetRole)) // }); AssociationChangedRules.SetEndpointRoles(elementLink); AssociationChangedRules.FixupForeignKeys(elementLink); // we could have a situation where there are no roles assigned (if 0/1-0/1 or 1-1). If we have exposed foreign keys, though, we can figure those out. if ((elementLink.SourceMultiplicity != Multiplicity.ZeroMany || elementLink.TargetMultiplicity != Multiplicity.ZeroMany) && (elementLink.SourceRole == EndpointRole.NotSet || elementLink.TargetRole == EndpointRole.NotSet) && !string.IsNullOrEmpty(elementLink.FKPropertyName)) { // which, if any, end has the foreign key properties in it? string firstFKPropertyName = elementLink.FKPropertyName.Split(',').First(); if (elementLink.Source.AllPropertyNames.Contains(firstFKPropertyName)) { elementLink.SourceRole = EndpointRole.Dependent; elementLink.TargetRole = EndpointRole.Principal; } else if (elementLink.Target.AllPropertyNames.Contains(firstFKPropertyName)) { elementLink.TargetRole = EndpointRole.Dependent; elementLink.SourceRole = EndpointRole.Principal; } } } }
private void ConfigureNewAssociation(UnidirectionalAssociation element) { SetInitialMultiplicity(element); SetTargetPropertyName(element); }
private void SetInitialMultiplicity(UnidirectionalAssociation element) { // valid unidirectional associations: // EF6 - entity to entity, entity to dependent // EFCore - entity to entity, entity to dependent // EFCore5Plus - entity to entity, entity to dependent, dependent to dependent, keyless to entity ModelRoot modelRoot = element.Source.ModelRoot; EFVersion entityFrameworkVersion = modelRoot.EntityFrameworkVersion; if (entityFrameworkVersion == EFVersion.EF6) { if (element.Source.IsEntity() && element.Target.IsEntity()) { element.SourceMultiplicity = Multiplicity.One; element.TargetMultiplicity = Multiplicity.ZeroMany; } if (element.Source.IsEntity() && element.Target.IsDependent()) { element.SourceMultiplicity = Multiplicity.One; element.TargetMultiplicity = Multiplicity.One; } } else if (entityFrameworkVersion == EFVersion.EFCore && !modelRoot.IsEFCore5Plus) { if (element.Source.IsEntity() && element.Target.IsEntity()) { element.SourceMultiplicity = Multiplicity.One; element.TargetMultiplicity = Multiplicity.ZeroMany; } if (element.Source.IsEntity() && element.Target.IsDependent()) { element.SourceMultiplicity = Multiplicity.One; element.TargetMultiplicity = Multiplicity.ZeroOne; } } else if (entityFrameworkVersion == EFVersion.EFCore && modelRoot.IsEFCore5Plus) { if (element.Source.IsEntity() && element.Target.IsEntity()) { element.SourceMultiplicity = Multiplicity.One; element.TargetMultiplicity = Multiplicity.ZeroMany; } if (element.Source.IsEntity() && element.Target.IsDependent()) { element.SourceMultiplicity = Multiplicity.One; element.TargetMultiplicity = Multiplicity.ZeroOne; } if (element.Source.IsDependent() && element.Target.IsDependent()) { element.SourceMultiplicity = Multiplicity.One; element.TargetMultiplicity = Multiplicity.ZeroOne; } if (element.Source.IsKeyless() && element.Target.IsEntity()) { element.SourceMultiplicity = Multiplicity.ZeroMany; element.TargetMultiplicity = Multiplicity.One; } } }