Typeorm Get full tree and relationships - orm

I've currently got a closure-Table structure entity called Units.
A unit can have a child of a different unit (Imagine a Platoon can have many squads)
A unit can have a many to many relation with Members as many members can be a unit and a unit can be in many members.
I want to display the full tree and relation. What do i do as at the moment i can just get the tree with all the children but no relations or vise versa

const treeCategoriesWithRelations = await repository.findTrees({ relations: ["sites"] });
// automatically joins the sites relation
Make sure your up to date with Typeorm :)

Related

Sql ER Diagram: product with parents relations

Hello I have the following situation:
I have a product instance table that is nothing more than a product already assigned to a department and employee.
Well, but I have the following business logic: the product can be an equipment, or a component, that is, a product can have children.
thinking how a computer case is a device that has patrimony_code, and has child products (components) such as:
motherboard,
memoirs,
vga
etc etc
and all of these components are connected to the equipment.
I arrived at this with less table:
But I encountered some problems:
my components would not need departament_id, as they do not belong to the department but to the equipment that there belongs to the department.
So I came to this modeling, but I don't know if it is a good thing to do this relationship, could someone help me if there is a more clean / solid solution for this?
if I have understood your description correctly, only a piece of equipment can be assigned directly to a department, not the individual components that make up the piece of equipment?
Assuming this is the case then I suggest you split this problem into 2 separate tasks as they are, in reality, unrelated and trying to treat them as a single model is causing confusion:
Model the relationship between an instance of a piece of equipment and a department
Model the hierarchy of components (and their instances) that make up a piece of equipment
Once you have these two models you can then relate them if you need to but logically they are separate and you can change one without affecting the other
Hope this helps?
UPDATE 1
(in response to your questions)
You construct 1 sub-model that covers your Equipment entity and the Component entity (plus any other relevant entities) that describe how your products are modelled.
Your construct a second sub-model that describes how equipment is assigned to a department.
The only entity that would be (necessarily) common to the 2 sub-models is the Equipment entity; though, obviously, you can display both sub-models on the same diagram if that is required - even though they are logically separate (apart from the one common entity: Equipment)

sql, define Separate relation to target table or get by joins

We're working on a CMS project with EF and MVC. We've Recently encountered a problem,
Please consider these tables:
Applications
Entities
ProductsCategories
Products
Relations are in this order:
Applications=>Entities=>ProductCategories=>Products
When we select a product by it's Id, always we should check if requested ProductsId is
just for a specific application stored in Applications table, These is for preventing load other applications products,
what is the best way to get a product for specific application id, We have two choice:
Instead of define a relation between products and applications we can do joins with productsCategories,entities, and applications to find it
=> when we want to get products we don't want to know about entities or other tables that we should join it to access applications
we can define a separate relation between products and applications and get it by simple select query
which of these is the best way and why?
Manish first thanks for your comment,Then please consider this that some of our tables does not have any relation with Entities for these tables we should define a relation with Entites to access Applications or define a separate as relation as mentioned above,For these tables we just define a relation and does not have extra work,except performance issue.still some of other tables has relations with entites so for this one defining a separat relation has extra work,
At last please consider this,in fact all of tables should access 'Entities' some by separate relation and others can access from there parents
actually for relation between products and entities we didn't define a separate relation because it doesn't has performance issue,But for relation between products and entities we should consider performance issue because in every request we should access Applications to check request Id is for current Application
So what is your idea?
Let's look at your options
Instead of defining a relationship, you can join the three tables to get the correct set of products: In this case, you won't have to make any database changes and anyway, you won't be fetching all the joined tables data, you would fetch only that data, which you have specified in your Linq Select List. But then, 3-tables join can be a little performance degrading when the number of rows will be very high at some point of time
You can define a separate relationship between the two said tables: In this case you would have to change your database structure, that would mean, making changes in your Entity and Entity Model, and lot of testing. No doubt, it will mean simple code, ease of usage which is always welcome.
So you see, there is no clear answer, ultimately it depends on you and your code environment what you want to go with, as for me, I would go for creating a separate relationship between the Application and Product entity, cause that would cause a cleaner code with a little less effort. Besides as they say, "Code around your data-structure, and not the otherway around"

Using Nested Intermediate Tables

I'm working with Laravel 4 and trying to setup a table structure for handling the following problem.
I have 3 tables: Players, Teams & Seasons
For each season, I will have multiple teams assigned and each team will have multiple players assigned.
I need to maintain historical data for each season, so I can't just connect the tables directly because changing the base player/teams tables would affect all seasons that way.
I connected the Seasons -> Teams table by using an intermediate table teams_in_season as follows:
class Season extends \Eloquent
{
public function teams()
{
return $this->belongsToMany('Team', 'teams_in_season');
}
}
That works as expected. The issue comes when I want to setup the player assignment. Naturally, I want to relate the teams to players so my line of thinking is that I need to create an intermediate table off of another intermediate table. Ex:
seasons -> teams_in_season -> players_in_teams -> players
If I went Seasons -> Players, that would work except that I wouldn't be able to eager load it that way.
seasons -> players_in_season -> players
$season->teams->players->get();
Essentially, the way the user enters data is to create a season, assign teams, assign players to teams, and then eventually add scoring. All data entered needs to be maintained and therefore the intermediate tables are necessary.
So, here's my question(s):
Can I nest/chain intermediate tables like this?
Is there a better way I can setup what I want to achieve?
This is a difficult problem. You will need to associate the players to the pivot table between teams and seasons. For that reason I would probably set that up as it's own model.
Relationships
Season hasMany SeasonTeam
SeasonTeam belongsTo Team
SeasonTeam belongsToMany Player
Eager Loading
Here is how you would list all the teams with their player roster using strictly the relationship methods and eager loading. This is 4 queries.
$season = Season::with('seasonTeams.players', 'seasonTeams.team')->find(1);
foreach ($season->seasonTeams as $seasonTeam)
{
echo $seasonTeam->team->name;
foreach ($seasonTeam->players as $player)
{
echo $player->name;
}
}
Joins
I won't draw out the details here but you could also use joins in the query builder to pull players that were part of a team playing in a given season. Check out the link below.
http://four.laravel.com/docs/queries#joins
I attempted a few different ideas (including Colin's answer), but decided to go a different route here. The main thing is that I felt that using $season->seasonTeams->teams() was a bit difficult to read. Also, attempting to chain an intermediary table off of another intermediary table felt a bit odd as well. The solution I came up with was this:
For teams, I stayed with my original design of seasons -> teams_in_seasons -> teams which allows me to lookup the instanced teams using $season->teams() and any pivot data necessary therein using the following relationship for the seasons model:
public function teams()
{
return $this->belongsToMany('Team', 'teams_in_season');
}
and inverse on teams:
public function seasons()
{
return $this->belongsToMany('Season', 'teams_in_season');
}
For players, instead of chaining off of the existing pivot table teams_in_season, I decided instead to connect the pivot table players_in_teams to both the seasons and teams table. To connect these together, I decided to use the Query Builder to build my own queries as follows on the Team model:
public function players($season_id, $team_id)
{
return DB::table('players')
->select(DB::raw('players.*'))
->join('players_in_team', 'players.id', '=', 'players_in_team.player_id')
->where('season_id', '=', $season_id)
->where('team_id', '=', $team_id)
->orderBy('last_name');
}
this will allow me to eager load the players for a given season team as follows:
$team->players($season->id, $team->id)->get()
This is a bit unorthodox, perhaps, but it works well for my purposes. I couldn't find another method that made as much sense logically to me. It also has the side effect of allowing me to add a method onto the Seasons model that will allow me to eager load all of the players for a given season such as:
Season::find(1)->players

Doctrine ORM Single Table Inheritance association problem (always Eager loading contrary to documentation))

I have an issue with single table inheritance and I'm not sure if I'm interpreting the documentation correctly.
First: I've not copied my code / entity mappings verbosely (or even using the correct syntax) here as I think the problem can be better communicated abstractly.
If this is not acceptable by all means say so and I'll add the full code - but it is LONG and I think my question can be answered without it.
If it helps I can draw
an ER diagram to try and communicate what I'm trying to do.
If you read the following and think 'hey that should work' - then tell me and I'll upload the real code
Second: I don't use lazy loading anywhere. Before accessing my entities I make sure that I load every related entity that I'm going to be accessing by writing DQL up front - so the following issue is fairly terminal to my application)
The Setup:
I have some entities - these make up the core of my application.
// #entity AnimalTrainingSchool
// oneToMany: trainingDepartment
fields: [name / location / year founded]
// #entity trainingDepartment
oneToMany: animalTrainer
oneToOne: building
fields: [capacity]
// #entity animalTrainer
fields: [name / age / qualification]
I access them frequently and in different contexts - but I commonly iterate though levels and access properties and relations for these entities.
foreach ($animalTrainingSchool as $school){
echo $school->getName() . ' at ' . $school->getLocation();
echo 'These are the training departments for this school:';
foreach ($school->getTrainingDepartments as $trainingDepartment){
echo $trainingDepartment->getAnimalTypeTrained() . ' are trained in this department';
}
}
I make sure that all of these are loaded up front by forming my DQL and executing it - to limit the number of SQL queries (to one).
This all works great (fairly standard stuff).
DQL Example : "SELECT ats, td, at FROM AnimalTrainingSchool ats JOIN AnimalTrainingSchool.trainingDepartments td JOIN td.animalTrainer at";
This sets up my collection and means that I can traverse it without having to issue additional queries
The Problem:
I have mapped other entites elsewhere in my application - very similarly to this (NOTE: My overall question is very similar to the below question with one MAJOR difference (see below)
Doctrine 2 Inheritance Mapping with Association
// NB: new awards are issued each time they are awarded - so it is meant to be a oneToOne relationships - the awards are unique
// #entity award
{id information / table information / discriminator map / inheritance type (SINGLE_TABLE)}
fields: [medalMaterial / award_serial_number]
//departmentAward extends award
oneToOne: trainingDepartment
//trainerAward extends award
oneToOne: animalTrainer
then I made the relationship bidirectional by modifying my initial entities
// #entity trainingDepartment
oneToMany: animalTrainer
oneToOne: building
oneToOne: departmentAward
fields: [capacity]
// #entity animalTrainer
fields: [name / age / qualification]
oneToOne: trainerAward
What Happens
Now when I access my original entities in exactly the same way as above - they automatically (eagerly) load the associated entity for their awards though I'm not telling them to.
This is especially bad when I'm iterating though a whole bunch of trainingDepartments / AnimalTrainers and Doctrine is executing an SQL statement for EVERY entity.
For 20 departments with 10 trainers in each - this is 200 additional queries.
//Given the exact same DQL and foreach loop as above (note that at no stage am I accessing awards) - I get a ton of extra queries that look like this
"SELECT award.property1, award.property2, award.property3 FROM awardTable LEFT JOIN trainingDepartmentTable ON award.awardee_id = trainingDepartmentTable.id and award.discriminatorColumn IN ('departmentAward')";
// or...
"SELECT award.property1, award.property2, award.property3 FROM awardTable LEFT JOIN animalTrainerTable ON award.awardee_id = animalTrainerTable.id and award.discriminatorColumn IN ('trainerAward')";
None of what is being generated is incorrect - it's just that having read the following question it seems to me like I have set this up as the documentation describes (and in the opposite way to #Matthieu; namely - that If I related my initial 3 entites to the LOWEST level entities
rather than the 'award' base class then they SHOULD be able to use proxies instead of attempting to eagerly load the entities.
Stackoverflow Question which is asking the opposite of what I am describing
Doctrine 2 Inheritance Mapping with Association
Relevant Doctrine Documentation
http://www.doctrine-project.org/docs/orm/2.0/en/reference/inheritance-mapping.html#performance-impact
There is a general performance
consideration with Single Table
Inheritance: If you use a STI entity
as a many-to-one or one-to-one entity
you should never use one of the
classes at the upper levels of the
inheritance hierachy as
“targetEntity”, only those that have
no subclasses. Otherwise Doctrine
CANNOT create proxy instances of this
entity and will ALWAYS load the entity
eagerly.
It seems to me that regardless of whether or not you are joining to the base level entity or a subclassed entity - Doctrine will eagerly load the associations and will not attempt to use proxies.
Again: I can post real code - but given the length of the question already I felt it was best not to. Any input greatly appreciated.
The inverse side of a oneToOne relationship can not be lazy loaded. In order to support lazy loading, Doctrine needs to create a proxy object, but proxy objects need to have an identifier associated with them. In the case of oneToOne relationships, the identifier is only available on the owning side. So the inverse relationship has to be loaded eagerly.
You should try to fetch join these associations if possible. Version 2.1 will automatically force fetch joins for inverse oneToOne relationships.

Many to Many relationship for single entity

I'm currently writing my first project using core data, and am having trouble working out how to query the relationship between some of my data.
In sql language, i have a Country table, which joins to a CountryLink M-M table containing the following fields:
countryId1
countryId2
bearing
What would be the correct way to model this in Core Data?
So far i have set up a single Country entity and a CountryLink entity (containing only a bearing field) and have added two 1-to-Many relationships from Country to CountryLink ('CountryLink1' and 'CountryLink2').
I've run the project and looked at the Sqlite db structure produced by Core Data (found here, using this sqlite gui), and the M-M join table seems correct (it contains the bearing, CountryLink1 and CountryLink2 fields), but i'm not sure how i would go about carrying out a fetch request for a single Country NSManagedObject to return an array of related Countries and their bearings?
Any help or related links would be much appreciated.
Thanks, Ted
First a word of warning:
Core Data is not SQL. Entities are not tables. Objects are not rows. Columns are not attributes. Core Data is an object graph management system that may or may not persist the object graph and may or may not use SQL far behind the scenes to do so. Trying to think of Core Data in SQL terms will cause you to completely misunderstand Core Data and result in much grief and wasted time.
See the Tequilla advice
Now, forgetting SQL and thinking in object graphs, your entities would look something like this:
Country{
someAttribute:string // or whatever
countryLinks<-->>CountryLink.country
}
CountryLink{
countryID1:string // or whatever
countryID2:string // or whatever
country<<-->Country.countryLinks
}
As you add Country and CountryLink objects you add them to the relationships as needed. Then to find CountryLink objects related to a specific Country object, you would perform a fetch on the Country entity for Country objects matching some criteria. Once you have that object, you simply ask it for the CountryLink objects in its countryLinks relationship. And your done.
The important thing to remember here is that entities in combination with managedObjects are intended to model real-world objects, conditions or events and the relationship between the same. e.g. a person and his cars. SQL doesn't really model or simulate, it just stores.