views:

151

answers:

1

Given the following fixed domain model:

public class Sentence {
    public int Id { get; private set; }
    public string Author { get; set; }
    public string[] Words { get; set; }
}

And the following proposed normalized database schema:

create table Sentence (
    Id int identity(1,1) not null primary key,
    Author varchar(450)
)
create table Word (
    Id int identity(1,1) not null primary key,
    Value varchar(450) not null unique
)
create table Sentence_Word (
    SentenceId int foreign key references Sentence (Id),
    WordId int foreign key references Word (Id),
    SortIndex int not null,
    primary key (SentenceId, WordId),
    unique (SentenceId, SortIndex)
)

How would you create the NHibernate mapping file?

This would be easy if we could add another domain entity Word and then change the Words property on Sentence to Word[] instead of string[] (it'd be a standard many-to-many entity relationship), but the string[] type for the property is required and cannot be changed.

This problem is similar to another StackOverflow question, except a many-to-many relationship needs to be used for proper data normalization (the set of words is relatively small while the combination of them into Sentences is huge), so it's not immediately clear how the standard value-based collections can be applied.

A: 

You could add the domain entity Word as you suggest, implement a collection of Word on Sentence, and continue to expose the Word[] array as string[]. Just dynamically build the Word[] array from the Word collection every time the property is accessed. If performance is a concern you could cache and rebuild the Word[] array only if the Word collection changed.

This would be easy if we could add another domain entity Word and then change the Words property on Sentence to Word[] instead of string[] (it'd be a standard many-to-many entity relationship), but the string[] type for the property is required and cannot be changed.

Jamie Ide
I've actually already started doing something similar. Unfortunately, the "Sentence" class is not easily changed to add another field, so what I'm trying is to add a subclass of Sentence with the additional property, an override on Words, and appropriate updates getters and setters to keep the two fields in sync. However, in order to dynamically populate Word[] from string[], the subclass needs to be aware of the persistence layer to load the Word entities -- I'm trying to maintain persistent-ignorant domain objects for true transparent persistence and was hoping to avoid anything like that.
iammichael