Dynamic View Services > Specifying Dynamic View Types > References > References and n-m Relations
 
References and n-m Relations
An n-m relation is an n-ary relation whose inverse relation is also an n-ary relation. In the Company example, the relation projects of the class Company is an n-m relation, because it is an n-ary relation of type IlsUsesList and its inverted relation, Project::companies, is also an n-ary relation (of type IlsInvertedRelationList).
Imagine you need to represent all the companies and projects as nodes in a graph with links connecting each company to the projects it contributes to.
The representation model includes the classes GraphR for graphs, NodeR for nodes and LinkR for links. Each link must reference its origin node and its destination node so that you can specify these references to unary-relations.
A solution here is to add a new class called CompanyProject and to split the inverted relation list Project::companies into n-ary relations to that class. The class CompanyProject is defined as follows.
Example
class CompanyProject : public IlsObject {
public:
    CompanyProject(Company* c=0, Project* p=0);
    IlsInvertedRelation<CompanyProject,Company> company;
    IlsInvertedRelation<CompanyProject,Project> project;
private:
    ILS_OBJECT_DECL(CompanyProject)
};
The inverted relation Project::companies is replaced by the inverted relation Project::companyProjects:
class Project: public IlsEntity
{
    ....
     IlsOwnsList<Project,CompanyProject> companyProjects;
     ....
};
The setContext and unsetContext functions used to invert the relation Company::projects are implemented as follows:
void Project::setContext(Company& c,void*,IlsRelationId){
   companyProjects<<new CompanyProject(&c,this);
}
 
void Project::unsetContext(Company& c,void*,IlsRelationId){
   IlsInvertedRelationList<Project,CompanyProject>::Iterator         i(companyProjects);
   CompanyProject* item;
 
   while (i >> item){
if (item->company.getValue()==&c)
i.shrinkBefore();
   }
}
Now, assuming you have defined a top level class Domain that uses all the companies in a relation companies and all the projects in a relation projects, you can specify the following view type:
view DomainGraph:
subscribe origin Domain:
represent Graph graph:
string label=identifier;
propagate companies;
propagate projects;
subscribe Company:
represent Node node:
ref<Graph> graph=view.origin->graph;
string label=identifier;
subscribe Project:
represent Node node:
Ref<Graph> graph=view.origin->graph;
string label=identifier;
propagate companyProjects;
subscribe CompanyProject:
represent Link link:
Ref<Node> fromNode=company->node;

Version 5.8
Copyright © 2014, Rogue Wave Software, Inc. All Rights Reserved.