Join Tables and Domain Models
In Domain Models arises often a design problem, when there is a relation between two entities and the relation itself holds additional attributes.
As an example a relational model would basically look like this:
Readings is basically a Join Table between articles and users, but it has additional columns on top of the two obligatory foreign keys.
When designing the associated object-model we are basically forced to create an entity for the reading, since there is no construct for ‘associations with attributes’ in current OO-Languages. But this often leaves a tainted feeling, because readings does not feel like a first-class entity in our model. Often we just want to navigate from articles to users, and for this scenario the reading should be transparent.
ActiveRecord in Ruby offers an interesting construct for this situation:
class Article < ActiveRecord::Base
has_many :users, :through => :readings
This allows direct navigation from an Article-Entity to its User-Entities like this:
article.users.each do |reader|
Now I was thinking of an elegant way to do something similar in C#, when the yield keyword came to mind:
public class Article
private readonly List<Reading> readings = new List<Reading>();
public void AddReading(User user, DateTime readTime, int rating)
readings.Add(new Reading(user, readTime, rating));
public IEnumerable<User> Readers
foreach (Reading reading in readings)
yield return reading.Reader;
The client code then looks like this:
foreach (User reader in article.Readers)
Ok, thats just the object model, mapping the whole thing to the database is another topic of its own …