I was hacking around trying to make a basic orm that has support for the one => one
and one => many
relationships. I think I succeeded somewhat, but I am curious about how to handle circular relationships.
Say you had something like this:
user::hasOne('car');
car::hasMany('wheels');
car::property('type');
wheel::hasOne('car');
You could then do this (theoretically):
$u = new user();
echo $u->car->wheels[0]->car->wheels[1]->car->wheels[2]->car->wheels[3]->type;
#=> "monster truck"
Now, I am not sure why you would want to do this. It seems like it wastes a whole pile of memory and time just to get to something that could have been done in a much shorter way. In my small ORM, I now have 4 copies of the wheel class, and 4 copies of the car class in memory, which causes a problem if I update one of them and save it back to the database, the rest get out of date, and could overwrite the changes that were already made.
How do other ORMs handle circular references? Do they even allow it? Do they go back up the tree and create a po开发者_StackOverflow社区inter to one of the parents? Do they let the coder shoot themselves in the foot if they are silly enough to go around in circles?
Circular references aren't a problem in an ORM. ORMS are lazy in their evaluation, meaning that they don't retrieve records until the record is accessed. In this way, there's no infinite loop issue. The same can go for writes, if you are lazy when you write, then the issues go away.
I believe most ORMs enforce a single unique object in memory. So, the first time you access car, car gets loaded into memory and it can be identified by a unique key. After going to the wheel and back to the car, the ORM realizes is already has that car in memory, so it doesn't load it again. This approach isn't without downsides, but each ORM works around those downsides in various ways.
精彩评论