Вот способ сделать это на уровне базы данных.
Когда мне нужно было это сделать, я разбил каждую таблицу кодов на две таблицы. Один содержал культурно-инвариантные данные: внутренний идентификатор кода, конечно, сам код, если код был культурно-инвариантным, и, возможно, другие столбцы (например, категории сортировки/группировки). Другой содержал данные, относящиеся к культуре: описания, коды, относящиеся к культуре, если это уместно, и так далее.
(Коды, зависящие от культуры, — это осиное гнездо; не пинайте его, если в этом нет необходимости. Может быть немного сложно уложить в голове мысль, что US
и EU
— это один и тот же код в разных языках. Но есть это страны, в которых может быть политически неприемлемо заставлять франкоязычных пользователей использовать US
в качестве аббревиатуры для États-Unis
. Ну, страна.)
Наличие кодовой таблицы, не зависящей от языка и региональных параметров, позволяет установить ограничения внешнего ключа между ней и основными таблицами, которые ее используют. Создание запросов, специфичных для культуры, довольно просто:
SELECT m.*, c.Code, ISNULL(s.Description, lf.Message)
FROM MainTable m
JOIN FooCodeData c ON m.CodeID = c.ID
LEFT JOIN CultureSpecificFooCodeData s ON s.CodeID = c.ID AND s.Culture = @Culture
JOIN LookupFailure lf ON lf.Culture = @Culture
Обратите внимание: если ваши коды зависят от культуры, вам даже не нужно присоединяться к FooCodeData
в этом запросе, вместо этого выбирая s.Code
.
Обратите также внимание на одну неотъемлемую слабость этого подхода, как показано LEFT JOIN
и ISNULL
в этом запросе: вы не можете создать ограничение, гарантирующее, что строка, специфичная для культуры, существует для каждой комбинации кода/культуры. Вот для чего предназначен LookupFailure
: он получает сообщение, относящееся к культуре, которое указывает, что запись кода, специфичная для культуры, не была введена для данного кода.
person
Robert Rossney
schedule
01.09.2009