I've spent some time reading your blog, the docs and some SO posts and I learned about denormalized references and a few tricks. I've converted my current EF entities to Raven as best as I could:
There are some differences:
- Removed some navigation properties, like User.CommentVotes and User.TopicVotes, which no longer make sense.
- Removed the hacks around EF not supporting enums (excluding the beta 5.0 release that needs .NET 4.5)
- Removed data annotations, since most are EF specific; can Raven handle data validation or do I have to do it in my application?
- Removed constructors and use plain arrays, for readability.
- Left the BuildModel static functions as they might help you better understand the relations between entities.
- Moved the "Computed Properties" from topic into auto properties, which would logically mirror the last edit (thus removing the need for a query).
- Created Ref classes to deal with references, storing a little more data than just the Id.
Please look at both and check if it is a sane conversion and more importantly, makes sense as a Raven model. I'd also appreciate criticism on my EF entities, as I will continue using it for a while until I can fully port the application, so a few improvements wouldn't hurt. I know that the topic edits do not handle specifications and tags; this is a flaw in the current design, I've not fixed it in the Raven model to make the differences easier to see, but ideally the edit will also store specs and tags, having those mirrored in the topic document itself for ease of accessibility.
For Comparison, I wrote a custom reference class "Computed Properties" which stores the topic ID and the respective comments and votes - there would be the CommentsForFirst and CommentsForSecond in the EF model. Is that a good thing to do? I might also make the Comparison class be something like Pair<Topic> and implement IEnumerable, so I could more easily use it in the code; how does Raven handle that? I'm worried it might treat each Comparison as a JSON array, which would be bad.
Lastly, Comment has a circular reference; a comment can be a reply to another, so I need to track that. What is the best way to do that? I currently use a FK key to the same table and a ReplyTo column; if that is NULL, the comment is not a reply, if it has a value it's the ID of the ascensor comment, so it's basically a tree: a comment can have many replies and can be a reply to a single comment.
Quite a lot of questions, but what are you gonna do :| Being used to SQL and being taught that SQL is the swiff army knife make it hard to think straight how to model objects and their relations in a non-relational database (heck, it's hard as hell to do it in a relational - seems to me "relational" is not the proper term for SQL databases, really).
Thank you very much for your effort so far Oren Eini, I've yet to see someone so dedicated to helping users of their products. I have subscribed to your blog and have a crapload of good posts bookmarked to read later.