views:

499

answers:

4

I'm playing around with LinqToSQL using an existing multi-lingual database, but I'm running into issues mapping a fairly important one-to-one relationship, so I suspect I am using the feature incorrectly for my database design.

Assume two tables, Category and CategoryDetail. Category contains the CategoryId (PK), ParentId and TemplateId. CategoryDetail contains the CategoryId (FK), LanguageId, Title and Description (in the appropriate language), with a combined PK of CategoryId and LanguageId.

If I drag-and-drop these tables into the LinqToSQL designer, the resultant object model has Category with a collection of CategoryDetail objects, which should never be the case. I'd like to be able to filter on LanguageId at the DataContext level, meaning that the whole Category is encapsulated within Category.CategoryDetail, not all language version encapsulated within Category.CategoryDetails.

This database worked fine on my old object library (an old-school custom BOL and DAL), but I fear that LinqToSQL would require this to change in order to give me the required result.

What is the best way to make this relationship (and language filtering) as seamless as possible?

A: 
alexmac
+1  A: 

I would have to assume cant be a true 1 to 1. Sounds like you have a PK of CatID and Lang ID on the Cat Details table. That would explain why its putting a collection. I could be wrong as you didnt mention the PK's of the CatDetails table

EDIT: A combined Pk of CatID and Lang ID makes that a 1:m relationship, and Linq to SQL is actually doing the correct thing. The only way it could possibly be a true 1:1 is if you had a lang ID on the cat table as well and that was part of the FK. I htink you may have to rethink what you want to do, or how you want to implement it.

mattlant
Sorry, yes, I've just clarified the context of the original post - I do have a combined PK. Is there a different DB structure I could have that would infer I wanted a 1-to-1 relationship?
tags2k
Not that I can think of at the top of my head, sorry. Add that into your post and see if anyone else has some ideas.
mattlant
+1  A: 

You can view properties of the association. (Right click on the line representing the association and show properties.) The properties will tell you if it is a one-to-one or one-to-many relationship. This is reflected in code by having either a single entity association (one-to-one) or an entity set association (one-to-many).

Jarrett Meyer
Thanks, I had completely missed this option! This technically is the answer, but as soon as I define it I get a "Sequence contains more than one element" exception, which is true. Duplicating the LanguageId would introduce redundancy, so I think it's time to hook up an XML web service to the old DB!
tags2k
Hey, thats great, important thing is you got the answer you needed.
mattlant
A: 

Since you don't have a 1:1 relationship the mapping alone will not provide the desired functionality. However it is easy to provide a method in the parent auto-generated class that does the job:

public partial class Category 
{
  public IEnumerable<CategoryDetail> GetDetailsByLanguage(string langID)
  {
    return this.CategoryDetails.Where(c => c.LangID == langID);
  }
}
Panos