I have status tables in my database, and "localised" tables that contain language-specific versions of those statuses. The point of the main status table is to define the status ID values, and other meta-data about the status. The "localised" table is to display the text representation in a UI, according to the users' preferred language. Here is an example schema:
create table [Language]
(
ID smallint primary key,
ISOName varchar(12)
)
create table EmployeeStatus
(
ID smallint primary key,
Code varchar(50)
)
create table EmployeeStatusLocalised
(
EmployeeStatusID smallint,
LanguageID smallint,
Description varchar(50),
constraint PK_EmployeeStatusLocalised primary key
(EmployeeStatusID, LanguageID),
constraint FK_EmployeeStatusLocalised_EmployeeStatus foreign key
(EmployeeStatusID) references EmployeeStatus (ID),
constraint FK_EmployeeStatusLocalised_Language foreign key
(LanguageID) references [Language] (ID)
)
create table Employee
(
ID int identity(1,1) primary key,
EmployeeName varchar(50) not null,
EmployeeStatusID smallint not null,
constraint FK_Employee_EmployeeStatus foreign key
(EmployeeStatusID) references EmployeeStatus (ID)
)
This is how I'd typically access that data:
select e.EmployeeName, esl.Description as EmployeeStatus
from Employee e
inner join EmployeeStatusLocalised esl on
e.EmployeeStatusID = esl.EmployeeStatusID and esl.LanguageID = 1
I'm not really happy that my LINQ to SQL is doing things in the most efficient way, though. Here's an example:
using (var context = new MyDbDataContext())
{
var item = (from record in context.Employees
select record).Take(1).SingleOrDefault();
Console.WriteLine("{0}: {1}", item.EmployeeName,
item.EmployeeStatus.EmployeeStatusLocaliseds.
Where(esl => esl.LanguageID == 1).Single().Description);
}