3

[更新]选择的方法如下,作为对这个问题的回应

你好,

我一直在寻找这个主题,但我真的找不到我要找的东西...

对于代码表,我的意思是:诸如“婚姻状况”、性别、特定法律或社会状态之类的东西……更具体地说,这些类型只有设置属性,并且项目不会很快改变(但可以)。属性是 ID、名称和描述。

我想知道如何在以下技术中最好地处理这些:

  • 在数据库中(多个表,一个具有不同代码键的表......?)

  • 创建类(可能类似于使用 ICode.Name 和 ICode.Description 继承 ICode)

  • 为此创建视图/演示者:应该有一个包含所有这些的屏幕,因此是类型列表(性别,婚姻状况......),然后是该类型的值列表,每个值都有名称和描述值列表中的项目。

这些是每个项目中都会出现的东西,所以必须有一些关于如何处理这些的最佳实践......

作为记录,我不太喜欢在这些情况下使用枚举......也欢迎在这里使用它们的任何论点。

[跟进]

好的,我得到了 CodeToGlory 和 Ahsteele 的一个很好的回答。让我们细化这个问题。

假设我们不是在谈论性别或婚姻状况,其价值肯定不会改变,而是关于具有名称和描述的“东西”,仅此而已。例如:社会地位、法律地位。

UI:我只想要一个屏幕。具有可能的 NameAndDescription 类型的列表框(我将称之为),具有所选 NameAndDescription 类型的可能值的列表框,然后是所选 NameAndDescription 类型项目的名称和描述字段。

在 View & Presenters 中如何处理?我在这里发现 NameAndDescription 类型需要从类名中提取的困难?

DB:多个查找表与单个查找表的优缺点是什么?

4

6 回答 6

2

使用数据库驱动的代码表非常有用。你可以做一些事情,比如定义数据的生命周期(使用开始和结束日期),实时将数据添加到表中,这样你就不必部署代码,你可以允许用户(当然有正确的权限)通过管理屏幕添加数据。

我建议始终使用自动编号主键而不是代码或描述。这允许您在不同的时间段内使用多个代码(名称相同但描述不同)。另外,大多数 DBA(根据我的经验)宁愿使用自动编号而不是基于文本的主键。

我会为每个编码列表使用一个表。您可以将多个代码全部放入一个不相关的表中(使用某种矩阵),但这会变得混乱,我只发现了一些甚至有用的情况。

于 2009-04-15T20:31:16.260 回答
1

这里有几件事:

  1. 使用明确且不会更改的枚举。例如,婚姻状况、性别等。

  2. 对上述未固定且可能随时间变化、增加/减少的项目使用查找表。

在数据库中有查找表是非常典型的。在您的业务层中定义一个可以与您的视图/演示文稿一起使用的键/值对象。

于 2009-04-15T20:19:37.910 回答
1

我决定采用这种方法:

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

在哪里:

  • CodeKeyManager 可以从 DB 中检索 CodeKeys (CodeKey=MaritalStatus)
  • Code 是一个用常量填充的类,返回字符串所以 Code.MaritalStatus = "maritalStatus"。这些常量映射到 CodeKey 表 > CodeKeyName
  • 在数据库中,我有 2 个表:
    • 带有 ID、CodeKeyName 的 CodeKey
    • 带有 CodeKeyId、ValueName、ValueDescription 的 CodeValue

D B:

替代文字 http://lh3.ggpht.com/_cNmigBr3EkA/SeZnmHcgHZI/AAAAAAAAAFU/2OTzmtMNqFw/codetables_1.JPG

班级代码:

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

类代码键:

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

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

类代码值:

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 Id 并使用字符串 (nchar) 代码来提高业务逻辑的可用性。

感谢您的回答!如果对此方法有任何意见,请做!

于 2009-04-15T22:55:54.650 回答
0

我倾向于对这种类型的数据使用表格表示。最终,如果您需要捕获数据,您将需要存储它。出于报告目的,最好有一个可以通过密钥从中提取数据的地方。出于规范化目的,我发现单用途查找表比多用途查找表更容易。

也就是说,枚举对于不会改变的事物(例如性别等)非常有效。

于 2009-04-15T20:24:05.157 回答
0

为什么大家都想把码表复杂化?是的,它们有很多,但它们很简单,所以保持这种方式。就像对待其他物体一样对待它们。你是领域的一部分,所以将它们建模为领域的一部分,没什么特别的。如果您在他们不可避免地需要更多属性或功能时不这样做,您将不得不撤消当前使用它的所有代码并重新编写它。

当然每个表(为了参考完整性,以便它们可用于报告)。

对于课程,当然还有一个,因为如果我编写一个方法来接收“性别”对象,我不希望能够不小心将它传递给“MarritalStatus”!让编译帮助您清除运行时错误,这就是它存在的原因。每个类都可以简单地继承或包含一个 CodeTable 类或其他任何东西,但这只是一个实现助手。

对于 UI,如果它确实使用继承的 CodeTable,我想您可以使用它来帮助您并在一个 UI 中维护它。

作为一项规则,不要搞乱数据库模型,不要搞乱业务模型,但你不想在 UI 模型中搞砸一点,这还不错。

于 2011-03-05T04:49:51.230 回答
0

我想考虑进一步简化这种方法。而不是定义代码(代码、代码键和代码值)的 3 个表,而只有一个包含代码类型和代码值的表呢?毕竟所有代码类型只是另一个代码列表。

也许像这样的表定义:

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

可以将检查约束添加到 Code 表中,以确保将有效的 CodeType 输入到表中:

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

这都是从防止数据库中查找表的泛滥并提供一个查找表的角度考虑的。我不知道这种设计在实践中是否会表现良好。

于 2018-12-09T20:49:43.047 回答