///------------------------------------------------------------------------------------------------- /// <summary> /// Gets a relationship. /// </summary> /// <param name="id"> /// The identifier. /// </param> /// <param name="schemaRelationship"> /// (Optional) the schema relationship. /// </param> /// <returns> /// The relationship. /// </returns> ///------------------------------------------------------------------------------------------------- public virtual IModelRelationship GetRelationship(Identity id, ISchemaRelationship schemaRelationship = null) { Contract.Requires(id, "id"); CheckInitialized(); return(L1Cache.GetElement(id, schemaRelationship) as IModelRelationship); }
///------------------------------------------------------------------------------------------------- /// <summary> An ISchemaElement extension method that adds an implicit constraint. </summary> /// <typeparam name="T"> Generic type parameter. </typeparam> /// <param name="metadata"> The metadata to act on. </param> /// <param name="expression"> The expression. </param> /// <param name="message"> The message. </param> /// <param name="propertyName"> (Optional) name of the property. </param> /// <returns> An ConstraintBuilder<T> </returns> ///------------------------------------------------------------------------------------------------- public static ConstraintBuilder <T> AddImplicitConstraint <T>(this ISchemaRelationship metadata, Func <T, bool> expression, DiagnosticMessage message, string propertyName = null) where T : IModelRelationship { Contract.Requires(metadata, "metadata"); Contract.Requires(expression, "expression"); Contract.Requires(message, "message"); return(new ConstraintBuilder <T>(metadata, propertyName, expression, message, true)); }
///------------------------------------------------------------------------------------------------- /// <summary> /// Initializes a new instance of the <see cref="AddRelationshipCommand" /> class. /// </summary> ///------------------------------------------------------------------------------------------------- public AddRelationshipCommand(ISchemaRelationship relationshipSchema, IModelElement start, Identity endId, Identity id = null, long?version = null) : base(start.DomainModel, version) { Contract.Requires(start, "start"); Contract.Requires(endId, "endId"); Contract.Requires(endId, "endId"); Contract.Requires(relationshipSchema, "relationshipSchema"); Start = start; EndId = endId; _domainModel = start.DomainModel; Id = id ?? DomainModel.IdGenerator.NextValue(relationshipSchema); if (String.Compare(Id.DomainModelName, start.DomainModel.Name, StringComparison.OrdinalIgnoreCase) != 0) { throw new InvalidIdException("The id must be an id of the specified domain model."); } if (relationshipSchema.IsEmbedded && start.Id == endId) { throw new CircularReferenceException("An element can not contain itself."); } SchemaRelationship = relationshipSchema; }
///------------------------------------------------------------------------------------------------- /// <summary> /// Adds an edge. /// </summary> /// <exception cref="DuplicateElementException"> /// Thrown when a Duplicate Element error condition occurs. /// </exception> /// <param name="id"> /// The identifier. /// </param> /// <param name="schemaRelationship"> /// Identifier for the metadata. /// </param> /// <param name="direction"> /// The direction. /// </param> /// <param name="endId"> /// The identifier of the end. /// </param> /// <returns> /// A GraphNode. /// </returns> ///------------------------------------------------------------------------------------------------- public virtual GraphNode AddEdge(Identity id, ISchemaRelationship schemaRelationship, Direction direction, Identity endId) { DebugContract.Requires(id, "id"); DebugContract.Requires(schemaRelationship, "schemaRelationship"); DebugContract.Requires(endId, "endId"); if ((direction & Direction.Outgoing) == Direction.Outgoing && _outgoings.ContainsKey(id) || (direction & Direction.Incoming) == Direction.Incoming && _incomings.ContainsKey(id)) { throw new DuplicateElementException("Duplicate relationship"); } // Check multi containers // TODO no it's valid if they are not all set (make a test in the command ???) //if ((direction & Direction.Incoming) == Direction.Incoming && schemaRelationship.IsEmbedded) //{ // if (_incomings.Any(r => r.Value.SchemaId == schemaRelationship.Id)) // return null; //} var edge = new EdgeInfo(id, schemaRelationship.Id, endId); return(new GraphNode(this, (direction & Direction.Outgoing) == Direction.Outgoing ? _outgoings.Add(id, edge) : _outgoings, (direction & Direction.Incoming) == Direction.Incoming ? _incomings.Add(id, edge) : _incomings )); }
internal IEnumerable <IModelRelationship> GetRelationships(ISchemaRelationship metadata = null, IModelElement start = null, IModelElement end = null, int skip = 0) { foreach (var e in InnerGraph.GetRelationships(metadata, start, end, skip)) { yield return((IModelRelationship)AddElement(e)); } }
///------------------------------------------------------------------------------------------------- /// <summary> /// Constructor. /// </summary> /// <exception cref="Exception"> /// Thrown when an exception error condition occurs. /// </exception> /// <param name="source"> /// Source for the. /// </param> /// <param name="schemaRelationship"> /// The schema relationship. /// </param> /// <param name="opposite"> /// (Optional) true to opposite. /// </param> /// <param name="readOnly"> /// (Optional) true to read only. /// </param> ///------------------------------------------------------------------------------------------------- public ObservableModelElementList(IModelElement source, ISchemaRelationship schemaRelationship, bool opposite = false, bool readOnly = false) : base(source, schemaRelationship, opposite, readOnly) { Contract.Requires(source, "source"); Contract.Requires(schemaRelationship, "schemaRelationship"); _synchronizationContext = source.DomainModel.Services.Resolve <ISynchronizationContext>(); if (_synchronizationContext == null) { throw new Exception("No synchronizationContext founded. You can define a synchronization context in the store with store.Register<ISynchronizationContext>."); } var query = DomainModel.Events.RelationshipAdded; var query2 = DomainModel.Events.RelationshipRemoved; var query3 = DomainModel.Events.PropertyChanged; relationshipAddedSubscription = query.Subscribe(a => Notify( Source != null ? a.Event.EndId : a.Event.StartId, Source != null ? a.Event.StartId : a.Event.EndId, a.Event.SchemaId, NotifyCollectionChangedAction.Add)); relationshipRemovedSubscription = query2.Subscribe(a => Notify( Source != null ? a.Event.EndId : a.Event.StartId, Source != null ? a.Event.StartId : a.Event.EndId, a.Event.SchemaId, NotifyCollectionChangedAction.Remove)); propertyChangedSubscription = query3.Subscribe(a => NotifyPropertyChanged( a.Event.Id, a.Event.SchemaId)); }
// Création d'une référence 0..1 à partir de l'élément courant ou vers l'élement courant si opposite vaut true internal void SetReference(ref Identity relationshipId, ISchemaRelationship relationshipSchema, IModelElement target, bool opposite) { DebugContract.Requires(relationshipSchema, "relationshipMetadata"); using (var session = EnsuresRunInSession()) { var commands = new List <IDomainCommand>(); IModelRelationship relationship = null; // !opposite ? this -> target : target -> this IModelElement start = !opposite ? this : null; IModelElement end = !opposite ? null : this; // Si l'identifiant est fourni c'est que la relation existe surement dèjà if (relationshipId != null) { relationship = DomainModel.GetRelationship(relationshipId); } if (relationship == null) { relationship = DomainModel.GetRelationships(relationshipSchema, start, end).FirstOrDefault(); } start = !opposite ? this : target; end = !opposite ? target : this; // Si cette relation existe dèjà mais sur un autre élement, on la supprime if (relationship != null) { // Si elle existe sur le même élement, c'est bon on la conserve if (end != null && relationship.End.Id == end.Id && start != null && relationship.Start.Id == start.Id) { relationshipId = relationship.Id; return; } // Suppression car elle pointe sur un élement diffèrent commands.Add(new RemoveRelationshipCommand(relationship)); } relationship = null; relationshipId = null; // Si elle n'a pas été mise à null if (end != null && start != null) { relationshipId = DomainModel.IdGenerator.NextValue(relationshipSchema); commands.Add(new AddRelationshipCommand(relationshipSchema, start, end, relationshipId)); } Session.Current.Execute(commands.ToArray()); if (session != null) { session.AcceptChanges(); } } }
protected virtual Tuple <GraphNode, GraphNode> GetTerminalNodes(ISchemaRelationship schema, Identity startId, Identity endId) { var start = _storage.GetNode(startId) as GraphNode; // Si le noeud opposé se trouve dans un autre domaine, end sera null et le domaine cible ne sera pas // mis à jour. Seul le noeud source est impacté var end = startId.DomainModelName == endId.DomainModelName ? _storage.GetNode(endId) as GraphNode : null; return(Tuple.Create(start, end)); }
public override GraphNode CreateRelationship(Identity id, ISchemaRelationship metaRelationship, Identity startId, Identity endId) { var node = base.CreateRelationship(id, metaRelationship, startId, endId); if (node != null) { _deletedElements.RemoveNode(id); } return(node); }
internal IModelRelationship CreateRelationship(Identity id, ISchemaRelationship relationshipSchema, IModelElement start, Identity endId, IModelRelationship relationship) { var r = InnerGraph.CreateRelationship(id, relationshipSchema, start.Id, endId); if (relationship == null) { relationship = (IModelRelationship)relationshipSchema.Deserialize(new SerializationContext(_domain, relationshipSchema, r)); } AddElement(relationship); return(relationship); }
///------------------------------------------------------------------------------------------------- /// <summary> /// Initializes a new instance of the <see cref="AddSchemaRelationshipCommand" /> class. /// </summary> /// <param name="domainModel"> /// The domain model. /// </param> /// <param name="id"> /// The identifier. /// </param> /// <param name="schemaRelationship"> /// The schema relationship. /// </param> /// <param name="start"> /// The start. /// </param> /// <param name="end"> /// The end. /// </param> /// <param name="version"> /// (Optional) the version. /// </param> ///------------------------------------------------------------------------------------------------- public AddSchemaRelationshipCommand(ISchema domainModel, Identity id, ISchemaRelationship schemaRelationship, ISchemaElement start, ISchemaElement end, long?version = null) : base(domainModel, version) { Contract.Requires(id, "id"); Contract.Requires(schemaRelationship, "schemaRelationship"); Contract.Requires(start, "start"); Contract.Requires(end, "end"); SchemaRelationship = schemaRelationship; Id = id; Start = start; End = end; }
protected override Tuple <GraphNode, GraphNode> GetTerminalNodes(ISchemaRelationship schema, Identity startId, Identity endId) { GraphNode start = null; GraphNode end = null; if (!IsDeleted(startId)) { base.GetGraphNode(startId, NodeType.EdgeOrNode, out start); if (start == null) { GraphNode extendedStart; _extendedGraph.GetGraphNode(startId, NodeType.EdgeOrNode, out extendedStart); if (extendedStart != null) { var rel = extendedStart as IModelRelationship; if (rel == null) { start = CreateEntity(startId, (ISchemaEntity)schema.Start); } else { start = CreateRelationship(startId, (ISchemaRelationship)schema.Start, rel.Start.Id, rel.End.Id); } } } } if (startId.DomainModelName == endId.DomainModelName && !IsDeleted(endId)) { base.GetGraphNode(endId, NodeType.EdgeOrNode, out end); if (end == null) { GraphNode extendedEnd; _extendedGraph.GetGraphNode(endId, NodeType.EdgeOrNode, out extendedEnd); if (extendedEnd != null) { var rel = extendedEnd as IModelRelationship; if (rel == null) { end = CreateEntity(endId, (ISchemaEntity)schema.End); } else { end = CreateRelationship(endId, (ISchemaRelationship)schema.End, rel.Start.Id, rel.End.Id); } } } } return(Tuple.Create(start as GraphNode, end as GraphNode)); }
///------------------------------------------------------------------------------------------------- /// <summary> /// Constructor. /// </summary> /// <exception cref="Exception"> /// Thrown when an exception error condition occurs. /// </exception> /// <param name="start"> /// The start. /// </param> /// <param name="end"> /// The end. /// </param> /// <param name="schemaRelationship"> /// (Optional) the schema relationship. /// </param> ///------------------------------------------------------------------------------------------------- public ModelRelationship(IModelElement start, IModelElement end, ISchemaRelationship schemaRelationship = null) { Contract.Requires(start, "start"); Contract.Requires(end, "end"); _startId = start.Id; _endId = end.Id; // Appel du ctor hérité Super(start.DomainModel, schemaRelationship, (dm, melId, mid) => new AddRelationshipCommand(mid as ISchemaRelationship, start, end.Id, melId)); if (((IModelRelationship)this).SchemaRelationship == null) { throw new TypeMismatchException(ExceptionMessages.SchemaMismatch); } }
protected override void DefineSchema(ISchema metaModel) { NamedElement = new SchemaEntity(metaModel, "NamedElement"); Library = new SchemaEntity(metaModel, "Library", NamedElement); Book = new SchemaEntity(metaModel, "Book"); Member = new SchemaEntity(metaModel, "Member", NamedElement); Loan = new SchemaEntity(metaModel, "Loan"); LoanReferencesBook = new SchemaRelationship("LoanReferencesBook", Loan, Book, Cardinality.ManyToOne, false, null, "Book"); LibraryHasBooks = new SchemaRelationship("LibraryHasBooks", Library, Book, Cardinality.OneToMany, true, null, "Books"); LibraryHasMembers = new SchemaRelationship("LibraryHasMembers", Library, Member, Cardinality.OneToMany, true, null, "Members"); LibraryHasLoans = new SchemaRelationship("LibraryHasLoans", Library, Loan, Cardinality.OneToMany, true, null, "Loans"); LoanReferencesMember = new SchemaRelationship("LoanReferencesMember", Loan, Member, Cardinality.ManyToOne, false, null, "Member"); NamedElement.DefineProperty <string>("Name"); Book.DefineProperty <string>("Title"); Book.DefineProperty <int>("Copies"); }
///------------------------------------------------------------------------------------------------- /// <summary> /// An IHyperstore extension method that creates a relationship. /// </summary> /// <exception cref="SessionRequiredException"> /// Thrown when a Session Required error condition occurs. /// </exception> /// <param name="store"> /// The store to act on. /// </param> /// <param name="schema"> /// The schema. /// </param> /// <param name="start"> /// The start. /// </param> /// <param name="end"> /// The end. /// </param> /// <param name="id"> /// (Optional) the identifier. /// </param> /// <returns> /// The new relationship. /// </returns> ///------------------------------------------------------------------------------------------------- public static IModelRelationship CreateRelationship(this IHyperstore store, ISchemaRelationship schema, IModelElement start, IModelElement end, Identity id = null) { Contract.Requires(store != null, "store"); Contract.Requires(schema != null, "schema"); Contract.Requires(start != null, "start"); Contract.Requires(end != null, "end"); if (Session.Current == null) { throw new SessionRequiredException(); } var domain = start.DomainModel; var cmd = new AddRelationshipCommand(schema, start, end, id); Session.Current.Execute(cmd); return(cmd.Relationship); }
///------------------------------------------------------------------------------------------------- /// <summary> /// Gets the relationships. /// </summary> /// <typeparam name="T"> /// Generic type parameter. /// </typeparam> /// <param name="metadata"> /// The metadata. /// </param> /// <param name="start"> /// The start. /// </param> /// <param name="end"> /// The end. /// </param> /// <param name="skip"> /// The skip. /// </param> /// <returns> /// An enumerator that allows foreach to be used to process the relationships in this collection. /// </returns> ///------------------------------------------------------------------------------------------------- public IEnumerable <T> GetRelationships <T>(ISchemaRelationship metadata, IModelElement start, IModelElement end, int skip = 0) where T : IModelRelationship { IEnumerable <NodeInfo> query; if (start != null) { query = GetEdges(start.Id, Direction.Outgoing, metadata, end != null ? end.Id : null); return(GetRelationshipsCore <T>(query, skip, metadata)); } else if (end != null) { query = GetEdges(end.Id, Direction.Incoming, metadata); return(GetRelationshipsCore <T>(query, skip, metadata)); } query = GetGraphNodes(NodeType.Edge); return(GetRelationshipsCore <T>(query, skip, metadata)); }
internal IModelElement GetReference(ref Identity relationshipId, ISchemaRelationship relationshipSchema, bool isOpposite) { DebugContract.Requires(relationshipSchema, "relationshipSchema"); var propertyName = isOpposite ? relationshipSchema.EndPropertyName : relationshipSchema.StartPropertyName; SetCalculatedPropertySource(propertyName); IModelRelationship relationship = null; if (relationshipId != null) { relationship = DomainModel.GetRelationship(relationshipId); } if (relationship == null) { var start = isOpposite ? null : this; var end = isOpposite ? this : null; relationship = DomainModel.GetRelationships(relationshipSchema, start, end).FirstOrDefault(); } if (relationship != null) { relationshipId = relationship.Id; var opposite = isOpposite ? relationship.Start : relationship.End; if (opposite != null) { var mel = _store.GetElement(opposite.Id); if (mel == null) { throw new InvalidElementException(opposite.Id, ExceptionMessages.InvalidReference); } return(mel); } return(opposite); } relationshipId = null; return(null); }
///------------------------------------------------------------------------------------------------- /// <summary> /// Gets the relationships. /// </summary> /// <param name="metadata"> /// (Optional) the metadata. /// </param> /// <param name="end"> /// (Optional) /// </param> /// <returns> /// An enumerator that allows foreach to be used to process the relationships in this collection. /// </returns> ///------------------------------------------------------------------------------------------------- public override IEnumerable <IModelRelationship> GetRelationships(ISchemaRelationship metadata = null, IModelElement end = null) { Queue <IModelElement> elements = new Queue <IModelElement>(); elements.Enqueue(this); while (elements.Count > 0) { var elem = elements.Dequeue(); foreach (var rel in DomainModel.GetRelationships(metadata, elem, end)) { yield return(rel); } var s = ((ISchemaElement)elem).SuperClass; if (s != null) { elements.Enqueue(s); } } }
///------------------------------------------------------------------------------------------------- /// <summary> /// Creates relationship core. /// </summary> /// <param name="id"> /// The identifier. /// </param> /// <param name="relationshipSchema"> /// The relationship schema. /// </param> /// <param name="start"> /// the start. /// </param> /// <param name="endId"> /// The end identifier. /// </param> /// <param name="relationship"> /// The relationship. /// </param> /// <returns> /// The new relationship core. /// </returns> ///------------------------------------------------------------------------------------------------- protected virtual IModelRelationship CreateRelationshipCore(Identity id, ISchemaRelationship relationshipSchema, IModelElement start, Identity endId, IModelRelationship relationship) { Contract.Requires(id, "id"); Contract.Requires(relationshipSchema, "relationshipSchema"); Contract.Requires(start, "start"); Contract.Requires(endId, "endId"); CheckInitialized(); using (var session = EnsuresRunInSession()) { relationship = L1Cache.CreateRelationship(id, relationshipSchema, start, endId, relationship); if (session != null) { session.AcceptChanges(); } return(relationship); } }
///------------------------------------------------------------------------------------------------- /// <summary> /// Gets the relationships. /// </summary> /// <param name="metadata"> /// The metadata. /// </param> /// <param name="start"> /// The start. /// </param> /// <param name="end"> /// The end. /// </param> /// <param name="skip"> /// The skip. /// </param> /// <returns> /// An enumerator that allows foreach to be used to process the relationships in this collection. /// </returns> ///------------------------------------------------------------------------------------------------- public IEnumerable <IModelRelationship> GetRelationships(ISchemaRelationship metadata, IModelElement start, IModelElement end, int skip = 0) { return(GetRelationships <IModelRelationship>(metadata, start, end, skip)); }
///------------------------------------------------------------------------------------------------- /// <summary> /// Adds an edge. /// </summary> /// <exception cref="NotImplementedException"> /// Thrown when the requested operation is unimplemented. /// </exception> /// <param name="id"> /// The identifier. /// </param> /// <param name="schemaRelationship"> /// Identifier for the metadata. /// </param> /// <param name="direction"> /// The direction. /// </param> /// <param name="endId"> /// The identifier of the end. /// </param> /// <returns> /// A GraphNode. /// </returns> ///------------------------------------------------------------------------------------------------- public override GraphNode AddEdge(Identity id, ISchemaRelationship schemaRelationship, Direction direction, Identity endId) { throw new NotImplementedException("Uses constructor instead"); }
protected IEnumerable <EdgeInfo> GetEdges(Identity sourceId, Direction direction, ISchemaRelationship metadata, Identity oppositeId = null) { DebugContract.Requires(sourceId); GraphNode v; if (!GetGraphNode(sourceId, NodeType.EdgeOrNode, out v) || v == null) { return(Enumerable.Empty <EdgeInfo>()); } return(GetEdgesCore(v, direction, metadata, oppositeId)); }
protected IEnumerable <EdgeInfo> GetEdgesCore(GraphNode source, Direction direction, ISchemaRelationship metadata, Identity oppositeId = null) { if (source == null) { yield break; } if ((direction & Direction.Outgoing) == Direction.Outgoing) { foreach (var info in GetGraphEdges(source, Direction.Outgoing)) { if (oppositeId == null || info.EndId == oppositeId) { if (metadata != null) { if (info.SchemaId != metadata.Id) { var m = _domainModel.Store.GetSchemaRelationship(info.SchemaId); if (!m.IsA(metadata)) { continue; } } } yield return(info); } } } if ((direction & Direction.Incoming) == Direction.Incoming) { foreach (var info in GetGraphEdges(source, Direction.Incoming)) { if (oppositeId == null || info.EndId == oppositeId) { if (metadata != null) { if (info.SchemaId != metadata.Id) { var m = _domainModel.Store.GetSchemaRelationship(info.SchemaId); if (!m.IsA(metadata)) { continue; } } } yield return(info); } } } }
protected IEnumerable <T> GetRelationshipsCore <T>(IEnumerable <NodeInfo> query, int skip, ISchemaRelationship metadata) where T : IModelRelationship { var cx = 0; var currentMetadata = metadata; foreach (var edge in query) { if (edge == null) { continue; } if (cx++ < skip) { continue; } GraphNode node; if (!GetGraphNode(edge.Id, NodeType.Edge, out node) || node == null) { continue; } if (currentMetadata == null || edge.SchemaId != currentMetadata.Id) { currentMetadata = _domainModel.Store.GetSchemaRelationship(edge.SchemaId); } var ctx = new SerializationContext(_domainModel, currentMetadata, node); yield return((T)currentMetadata.Deserialize(ctx)); } }
private bool SerializeReference(IModelElement element, ISchemaRelationship relationshipSchema, bool outDirection, bool insertComma) { bool many = (outDirection && (relationshipSchema.Cardinality & Cardinality.OneToMany) == Cardinality.OneToMany) || (!outDirection && (relationshipSchema.Cardinality & Cardinality.ManyToOne) == Cardinality.ManyToOne); bool first = !insertComma || !many; if (insertComma) { Write(','); } insertComma = true; Write('"', true); Write(outDirection ? relationshipSchema.StartPropertyName : relationshipSchema.EndPropertyName, false); Write('"'); Write(':'); if (many) { Write('[', true); _depth++; first = true; } var query = outDirection ? element.GetRelationships(relationshipSchema) : element.DomainModel.GetRelationships(relationshipSchema, end: element); foreach (var rel in query) { if (!ShouldSerialize(rel)) { continue; } if (!first) { Write(','); } first = false; var terminal = outDirection ? rel.End : rel.Start; if (terminal == null) { continue; } if (HasOption(JSonSerializationOption.Json)) { if (IsReference(terminal)) { //Write('"', true); //Write(outDirection ? relationshipSchema.EndPropertyName : relationshipSchema.StartPropertyName, false); //Write('"'); //Write(':'); Write('{', true); _depth++; WriteJsonId(terminal, false, true); _depth--; Write('}', true); continue; } } if (!HasOption(JSonSerializationOption.Json) && (HasOption(JSonSerializationOption.SerializeByReference) || _serialized.Contains(terminal.Id))) { Write('{', true); _depth++; if (!HasOption(JSonSerializationOption.SerializeIdentity)) { throw new JsonSerializationException("Circular dependency detected. You must set the JSonSerializationOption.SerializeIdentity to serialize this object graph."); } WriteKeyString("_eid", GetId(terminal), false); if (HasOption(JSonSerializationOption.SerializeRelationship)) { WriteKeyString("_rid", GetId(rel)); } if (HasOption(JSonSerializationOption.SerializeSchemaIdentity)) { WriteKeyValue("_eshid", GetSchemaIndex(GetSchemaInfo(terminal).Id)); WriteKeyValue("_rshid", GetSchemaIndex(GetSchemaInfo(rel).Id)); } _depth--; Write('}', true); } else { SerializeElement(terminal, false); } } if (many) { _depth--; Write(']', true); } return(insertComma); }
///------------------------------------------------------------------------------------------------- /// <summary> /// An IDomainModel extension method that creates a relationship. /// </summary> /// <exception cref="SessionRequiredException"> /// Thrown when a Session Required error condition occurs. /// </exception> /// <param name="domain"> /// the domain model. /// </param> /// <param name="schema"> /// The schema. /// </param> /// <param name="startId"> /// The start identifier. /// </param> /// <param name="endId"> /// The end identifier. /// </param> /// <param name="id"> /// (Optional) the identifier. /// </param> /// <returns> /// The new relationship. /// </returns> ///------------------------------------------------------------------------------------------------- public static IModelRelationship CreateRelationship(this IDomainModel domain, ISchemaRelationship schema, Identity startId, Identity endId, Identity id = null) { Contract.Requires(domain != null, "domain"); Contract.Requires(schema != null, "schema"); Contract.Requires(startId != null, "startId"); Contract.Requires(endId != null, "endId"); if (Session.Current == null) { throw new SessionRequiredException(); } var start = domain.GetElement(startId); if (start == null) { throw new InvalidElementException(startId); } var cmd = new AddRelationshipCommand(schema, start, endId, id); Session.Current.Execute(cmd); return(cmd.Relationship); }
///------------------------------------------------------------------------------------------------- /// <summary> /// Constructor. /// </summary> /// <param name="relationshipSchema"> /// The relationship schema. /// </param> /// <param name="start"> /// The start element. /// </param> /// <param name="end"> /// The end. /// </param> /// <param name="id"> /// (Optional) The identifier. /// </param> /// <param name="version"> /// (Optional) the version. /// </param> ///------------------------------------------------------------------------------------------------- public AddRelationshipCommand(ISchemaRelationship relationshipSchema, IModelElement start, IModelElement end, Identity id = null, long?version = null) : this(relationshipSchema, start, end.Id, id, version) { }
///------------------------------------------------------------------------------------------------- /// <summary> /// Specialised constructor for use only by derived classes. /// </summary> /// <param name="element"> /// The element. /// </param> /// <param name="schemaRelationship"> /// The schema relationship. /// </param> /// <param name="opposite"> /// (Optional) true to opposite. /// </param> /// <param name="readOnly"> /// (Optional) true to read only. /// </param> ///------------------------------------------------------------------------------------------------- protected AbstractModelElementCollection(IModelElement element, ISchemaRelationship schemaRelationship, bool opposite = false, bool readOnly = false) : base(element, schemaRelationship, opposite) { _readOnly = readOnly; }
///------------------------------------------------------------------------------------------------- /// <summary> /// Creates the relationship. /// </summary> /// <param name="schemaRelationship"> /// The schema relationship. /// </param> /// <param name="start"> /// The start. /// </param> /// <param name="end"> /// The end. /// </param> /// <returns> /// The new relationship. /// </returns> ///------------------------------------------------------------------------------------------------- public IModelRelationship CreateRelationship(ISchemaRelationship schemaRelationship, IModelElement start, IModelElement end) { return(InvokeModelRelationshipConstructorForType(schemaRelationship, start, end, schemaRelationship.ImplementedType)); }
///------------------------------------------------------------------------------------------------- /// <summary> /// Gets the relationships. /// </summary> /// <param name="metadata"> /// (Optional) the metadata. /// </param> /// <param name="end"> /// (Optional) /// </param> /// <returns> /// An enumerator that allows foreach to be used to process the relationships in this collection. /// </returns> ///------------------------------------------------------------------------------------------------- public virtual IEnumerable <IModelRelationship> GetRelationships(ISchemaRelationship metadata = null, IModelElement end = null) { return(DomainModel.GetRelationships(metadata, this, end)); }