лучшие практики с кодом или таблицами поиска - PullRequest
3 голосов
/ 16 апреля 2009

[ОБНОВЛЕНИЕ] Выбранный подход ниже, как ответ на этот вопрос

Привет,

Я искал эту тему, но не могу найти то, что искал ...

Под таблицами кодов я имею в виду: такие вещи, как «семейное положение», пол, конкретные правовые или социальные состояния ... Более конкретно, эти типы имеют только установленные свойства, и элементы не собираются изменяться в ближайшее время (но могут). Свойства: идентификатор, имя и описание.

Мне интересно, как справиться с этим лучше всего в следующих технологиях:

  • в базе данных (несколько таблиц, одна таблица с разными кодовыми ключами ...?)

  • создание классов (возможно, что-то вроде наследования ICode с ICode.Name и ICode.Description)

  • создание представления / презентатора для этого: должен быть экран, содержащий все из них, поэтому список типов (пол, семейное положение ...), а затем список значений для этого типа с имя и описание для каждого элемента в списке значений.

Это вещи, которые появляются в каждом отдельном проекте, поэтому должна быть лучшая практика, как справиться с этими ...

Кстати, я не очень люблю использовать перечисления для этих ситуаций ... Любые аргументы по поводу их использования здесь тоже приветствуются.

[ПОСЛЕДУЮЩИЙ]

Хорошо, я получил хороший ответ от CodeToGlory и Ahsteele. Давайте уточним этот вопрос.

Скажем, мы говорим не о поле или семейном положении, значения которого определенно не изменятся, а о "вещах", которые имеют имя и описание, но не более того. Например: социальные статусы, правовые статусы.

UI: Я хочу только один экран для этого. Окно списка с возможными типами NameAndDescription (я назову их так), поле со списком возможных значений для выбранного типа NameAndDescription, а затем поле Имя и описание для выбранного элемента типа NameAndDescription.

Как это можно обработать в View & Presenters? Я нахожу здесь трудность в том, что типы NameAndDescription должны быть извлечены из имени класса?

DB: Каковы плюсы / минусы для нескольких таблиц поиска и сравнения?

Ответы [ 6 ]

2 голосов
/ 16 апреля 2009

Использование таблиц кода на основе базы данных может быть очень полезным. Вы можете сделать такие вещи, как определить срок действия данных (используя даты начала и окончания), добавить данные в таблицу в режиме реального времени, чтобы вам не приходилось развертывать код, и вы можете разрешить пользователям (с правильными привилегиями, конечно) добавить данные через административные экраны.

Я бы рекомендовал всегда использовать первичный ключ autonumber, а не код или описание. Это позволяет вам использовать несколько кодов (с одинаковыми именами, но разными описаниями) в разные периоды времени. Кроме того, большинство администраторов баз данных (по моему опыту) предпочитают использовать автонумерацию над текстовыми первичными ключами.

Я бы использовал одну таблицу для каждого закодированного списка. Вы можете поместить несколько кодов в одну таблицу, которая не имеет отношения (используется своего рода матрица), но это становится беспорядочным, и я нашел только пару ситуаций, где это было бы даже полезно.

1 голос
/ 16 апреля 2009

Я решил пойти с этим подходом:

CodeKeyManager mgr = new CodeKeyManager();
CodeKey maritalStatuses = mgr.ReadByCodeName(Code.MaritalStatus);

Где:

  • CodeKeyManager может извлекать CodeKeys из БД (CodeKey = MaritalStatus)
  • Код - это класс, заполненный константами, возвращающими строки, поэтому Code.MaritalStatus = "maritalStatus". Эти константы соответствуют таблице CodeKey> CodeKeyName
  • В базе данных у меня есть 2 таблицы:
    • CodeKey с идентификатором, CodeKeyName
    • CodeValue с CodeKeyId, ValueName, ValueDescription

DB:

альтернативный текст http://lh3.ggpht.com/_cNmigBr3EkA/SeZnmHcgHZI/AAAAAAAAAFU/2OTzmtMNqFw/codetables_1.JPG

Код класса:

public class Code
{
    public const string Gender = "gender";
    public const string MaritalStatus = "maritalStatus";
}

Класс CodeKey:

public class CodeKey
{
    public Guid Id { get; set; }
    public string CodeName { get; set; }

    public IList<CodeValue> CodeValues { get; set; }
}

Класс CodeValue:

public class CodeValue
{
    public Guid Id { get; set; }

    public CodeKey Code { get; set; }

    public string Name { get; set; }
    public string Description { get; set; }

}

На мой взгляд, самый простой и эффективный способ:

  • Все кодовые данные могут отображаться одинаковым образом (в том же виде / докладчик)
  • Мне не нужно создавать таблицы и классы для каждой кодовой таблицы, которая должна прийти
  • Но я все еще могу легко вывести их из базы данных и легко использовать с константами CodeKey ...
  • NHibernate может справиться с этим тоже легко

Единственное, что я все еще рассматриваю, - это выбросить идентификаторы GUID и использовать строковые (nchar) коды для удобства использования в бизнес-логике.

Спасибо за ответы! Если есть какие-либо замечания по этому подходу, пожалуйста, сделайте!

1 голос
/ 16 апреля 2009

Пара вещей здесь:

  1. Используйте перечисления, которые явно понятны и не изменятся. Например, MaritalStatus, Gender и т. Д.

  2. Используйте таблицы поиска для элементов, которые не зафиксированы, как указано выше, и могут изменяться, увеличиваться / уменьшаться со временем.

Очень типично иметь таблицы поиска в базе данных. Определите ключ / значение объекта на вашем бизнес-уровне, который может работать с вашим представлением / презентацией.

0 голосов
/ 09 декабря 2018

Я бы хотел еще больше упростить этот подход. Вместо 3 таблиц, определяющих коды (Code, CodeKey и CodeValue), как насчет одной таблицы, которая содержит как типы кодов, так и значения кодов? Ведь типы кодов - это просто другой список кодов.

Возможно определение таблицы примерно так:

CREATE TABLE [dbo].[Code](
    [CodeType] [int] NOT NULL,
    [Code] [int] NOT NULL,
    [CodeDescription] [nvarchar](40) NOT NULL,
    [CodeAbreviation] [nvarchar](10) NULL,
    [DateEffective] [datetime] NULL,
    [DateExpired] [datetime] NULL,
CONSTRAINT [PK_Code] PRIMARY KEY CLUSTERED 
(
    [CodeType] ASC,
    [Code] ASC
)
GO

Может быть корневая запись с CodeType = 0, Code = 0, которая представляет тип для CodeType. Все записи CodeType будут иметь CodeType = 0 и Code> = 1. Вот некоторые примеры данных, которые могут помочь прояснить ситуацию:

SELECT CodeType, Code, Description FROM Code

Results:

CodeType    Code    Description
--------    ----    -----------
0           0       Type
0           1       Gender
0           2       Hair Color
1           1       Male
1           2       Female
2           1       Blonde
2           2       Brunette
2           3       Redhead

В таблицу кодов можно добавить проверочное ограничение, чтобы убедиться, что в таблицу введен действительный кодовый тип:

ALTER TABLE [dbo].[Code] WITH CHECK ADD CONSTRAINT [CK_Code_CodeType]   
CHECK (([dbo].[IsValidCodeType]([CodeType])=(1)))
GO

Функция IsValidCodeType может быть определена так:

CREATE FUNCTION [dbo].[IsValidCodeType]
(
    @Code INT
)
RETURNS BIT
AS
BEGIN
    DECLARE @Result BIT
    IF EXISTS(SELECT * FROM dbo.Code WHERE CodeType = 0 AND Code = @Code)
        SET @Result = 1
    ELSE
        SET @Result = 0
    RETURN @Result
END
GO

Одна из поднятых проблем состоит в том, как обеспечить, чтобы таблица с столбцом кода имела правильное значение для этого типа кода. Это также может быть обеспечено проверочным ограничением с использованием функции.

Вот таблица Person, в которой есть столбец пола. Рекомендуется присваивать имена всем столбцам кода с описанием типа кода (в данном примере «Пол»), за которым следует слово «Код»:

CREATE TABLE [dbo].[Person](   
    [PersonID] [int] IDENTITY(1,1) NOT NULL,
    [LastName] [nvarchar](40) NULL,
    [FirstName] [nvarchar](40) NULL,
    [GenderCode] [int] NULL,
CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED ([PersonID] ASC)
GO

ALTER TABLE [dbo].[Person] WITH CHECK ADD CONSTRAINT [CK_Person_GenderCode] 
CHECK (([dbo].[IsValidCode]('Gender',[Gendercode])=(1)))
GO

IsValidCode можно определить следующим образом:

CREATE FUNCTION [dbo].[IsValidCode]
(
    @CodeTypeDescription NVARCHAR(40),
    @Code INT
)
RETURNS BIT
AS
BEGIN
    DECLARE @CodeType INT
    DECLARE @Result BIT

    SELECT @CodeType = Code
    FROM dbo.Code
    WHERE CodeType = 0 AND CodeDescription = @CodeTypeDescription

    IF (@CodeType IS NULL)
    BEGIN
        SET @Result = 0
    END
    ELSE
    BEGiN
    IF EXISTS(SELECT * FROM dbo.Code WHERE CodeType = @CodeType AND Code = @Code)
        SET @Result = 1
    ELSE
        SET @Result = 0
    END

    RETURN @Result
END
GO

Может быть создана другая функция для предоставления описания кода при запросе таблицы, в которой есть столбец кода. Вот Пример запроса таблицы Person:

SELECT PersonID,
    LastName,
    FirstName,
    GetCodeDescription('Gender',GenderCode) AS Gender
FROM Person

Все это задумывалось с точки зрения предотвращения распространения справочных таблиц в базе данных и предоставления одной справочной таблицы. Я понятия не имею, будет ли этот дизайн хорошо работать на практике.

0 голосов
/ 05 марта 2011

Почему все хотят усложнять кодовые таблицы? Да, их много, но они просты, так что держите их так. Просто относитесь к ним как к любому другому предмету. Они являются частью домена, поэтому моделируйте их как часть домена, ничего особенного. Если вам это не нужно, когда им неизбежно понадобятся дополнительные атрибуты или функции, вам придется отменить весь код, который в данный момент использует его, и переработать его.

Одна таблица на каждый (для ссылочной целостности и чтобы они были доступны для отчетов).

Для классов, опять же по одному на каждый курс, потому что, если я напишу метод для получения объекта "Gender", я не хочу иметь возможность случайно передать ему "MarritalStatus"! Пусть компиляция поможет вам отсеять ошибку времени выполнения, поэтому она есть. Каждый класс может просто наследовать или содержать класс CodeTable или любой другой, но это просто помощник реализации.

Для пользовательского интерфейса, если он действительно использует унаследованный CodeTable, я полагаю, вы могли бы использовать это, чтобы помочь вам и просто сохранить его в одном пользовательском интерфейсе.

Как правило, не путайте модель базы данных, не путайте бизнес-модель, но если вы хотите немного обойтись в модели пользовательского интерфейса, это не так уж и плохо.

0 голосов
/ 16 апреля 2009

Я склоняюсь к использованию табличного представления для этого типа данных. В конечном счете, если вам нужно захватить данные, вам нужно будет их сохранить. Для целей отчетности лучше иметь место, откуда вы можете получить эти данные с помощью ключа. В целях нормализации я считаю, что одноразовые таблицы поиска проще, чем многоцелевые таблицы поиска.

При этом перечисления работают довольно хорошо для вещей, которые не меняются, например, пол и т. Д.

...