2

假设我们有一个所有国家的代码列表,包括他们的国家代码。国家代码是国家表的主键,它在数据库的许多地方用作外键。在我的应用程序中,国家通常显示为多个表单的下拉列表。

过去存在的一些国家已经不复存在,例如塞尔维亚和黑山,其国家代码为 SCG。

我有两个目标:

  • 不允许用户使用这些旧值(因此在插入数据时这些值不应在下拉列表中可见)
  • 用户应该仍然能够(只读)打开旧的东西,在这种情况下,不推荐使用的值应该在下拉列表中可见。

我看到两个选项:

  • 重命名不推荐使用的值,例如从“CountryName”到“!!!!!CountryName”。这种方法最容易实现,但也有明显的缺点。
  • 将 IsActive 列添加到国家表中,并将所有不推荐使用的值设置为 false,将所有其他值设置为 true。在用户可以插入数据的所有表单上,仅显示活动值。在只读表单上,我们可以显示所有值(包括已弃用的值),以便用户能够显示旧数据。但是在我的一些表单上,用户应该也可以编辑数据,这意味着不推荐使用的值应该对他隐藏。这意味着,每个 Dropbox 都应该有一些像这样的初始化逻辑:如果显示的数据是只读的,则在 Dropbox 中包含不推荐使用的值,如果数据也用于编辑,则排除它们。但这也是很多工作并且容易出错。

还有其他想法?

4

4 回答 4

6

正如您所描述的,我经常处理这种情况,并使用“活动”标志来解决问题。当我用值填充下拉列表时,我只加载“活动”数据并包含最多 1 个不推荐使用的值,但前提是它正在被使用。(即,如果我正在查看人员记录,并且该人员的国家/地区已弃用,则该国家/地区将与活动国家/地区一起包含在下拉列表中。我在只读和编辑模式下执行此操作,因为在我的案例,如果一个人记录(例如)列出了一个已弃用的国家,他们可以继续使用它,但是一旦他们将其更改为非弃用的国家,然后保存它,他们就永远无法切换回来(你的用例可能会有所不同)。

所以关键的区别是,即使在只读模式下,我也不会将所有已弃用的国家/地区添加到 DDL,而只是将已弃用的国家/地区添加到我正在查看的记录中,即使那样,也只有当该记录是已经在使用了。

这是我在加载下拉列表时使用的逻辑示例:

    protected void LoadSourceDropdownList(bool AddingNewRecord, int ExistingCode)
    {
        using (Entities db = new Entities())
        {
            if (AddingNewRecord) // when we are adding a new record, only show 'active' items in the drop-downlist.
                ddlSource.DataSource = (from q in db.zLeadSources where (q.Active == true) select q);

            else // for existing records, show all active items AND the current value.
                ddlSource.DataSource = (from q in db.zLeadSources where ((q.Active == true) || (q.Code == ExistingCode)) select q);

            ddlSource.DataValueField = "Code";
            ddlSource.DataTextField = "Description";
            ddlSource.DataBind();

            ddlSource.Items.Insert(0, "--Select--");
            ddlSource.Items[0].Value = "0";
        }
    }
于 2012-08-21T14:01:00.067 回答
1

如果您将记录显示为只读,为什么还要加载常规数据呢?

这是我要做的:

无论如何,该记录都将包含国家代码,我还建议返回国家描述(诚然这会降低效率),但是当用户加载“旧东西”时,业务服务会认识到该记录将是只读的,而且您不必费心加载国家/地区列表(这会使事情变得更有效率)。

在我的演示服务中,我通常会检查国家列表是否为空。如果不是 (r/w) 将数据加载到列表框中,如果是 (r/o) 从记录中的数据填充列表框 - 列表中的单个条目等于只读。

于 2012-08-21T14:51:49.863 回答
0

您可以使用 CollectionViewSource 进行过滤,也可以只创建一个使用 LINQ 过滤完整列表的 Public Enumerable。

CollectionViewSource 类

LINQ FieldDef.DispSearch 是活动条件。IEnumerable 的性能比 List 好一点。

public IEnumerable<FieldDefApplied> FieldDefsAppliedSearch
{
    get
    {
        return fieldDefsApplied.Where(df => df.FieldDef.DispSearch).OrderBy(df => df.FieldDef.DispName);
    }
}
于 2012-08-21T13:57:01.373 回答
0

为什么您仍想显示(例如)带有旧国家代码的客户地址?
如果我理解正确,您目前仍然有指向“塞尔维亚和黑山”的“地址”记录。我认为,如果您解决了该问题,那么您当前的问题将不存在。

“国家”一词可能有点误导:并非 ISO 3166 中的所有“国家”实际上都是独立的。相反,它们中的许多是地理上独立的领土,在法律上是其他国家的一部分或附属国。

另请注意,“撤回的国家/地区代码”保留 5 年,这意味着 5 年后可以重复使用。因此,不再使用国家/地区代码本身作为主键对我来说是有意义的,特别是如果由于历史原因您需要回溯以前的国家/地区代码。

那么为什么不制作指向新国家/地区ID的“撤回”字段/表。您仍然可以检查(例如,在 sql 中,因为您已经在使用表)该字段是否为空,以便在需要时进行真/假检查。

我的看法是:“国家”代码可能会改变,国家可能会合并,国家可能会分裂。

如果国家/地区发生变化或合并,您可以通过简单的查询来更新您的地址记录。

如果国家有分歧,您需要一种方法来确定哪个地址属于哪个国家。你可以使用一些自动化系统来做到这一点(并写冗长的书)。
或者
(当它是一个类似网站的论坛时),您可以要求仍然有一个退出国家/地区的用户指向他们帐户中的多个替代项,以便在登录时更新他们的国家/地区条目,他们只能从新国家/地区列表中进行选择在撤回的字段中指定。

想想这个简化的国家表设置:

id  cc  cn                     withdrawn
1   DE  Germany
2   CS  Serbia and Montenegro  6,7
3   RH  Southern Rhodesia      5
4   NL  The Netherlands        
5   ZW  Zimbabwe
6   RS  Serbia
7   ME  Montenegro

在此示例中,国家 ID 为 3 的地址记录通过对国家 ID 5 的查询进行更新,无需用户交互(或其他解决方案)。
但是,指定 country-id 2 的地址记录将被要求选择 country-id 6 或 7(当然在呈现给用户的文本中,您使用国家名称)或选择执行您的自定义自动更新例程。

另请注意:“撤回”是一个重复组,因此您可以/应该将其放入单独的表格中。

在您的场景中实施此想法(无需停机):

  • sql 语句以数字 id 作为主键构建一个新的国家/地区表。
  • sql 语句使用新字段“country-id”更新地址记录,并使用与该记录的地址字段中指定的国家/地区代码对应的新国家/地区表中的国家/地区 ID 填充此字段。
  • (sql 语句)创建撤回的表并在其中填充正确的数据。
  • 然后重写为表单提供数据的 sql 语句
  • 添加检查并“要求用户更新国家/地区”-例程
  • 让新形式上线
  • 等待/查看意外错误
  • 从“地址”表中删除旧的国家/地区表和(现在未使用的)国家/地区代码列

我很好奇其他专家对这个想法的看法!!

于 2012-08-21T13:57:21.357 回答