如何轻松地将记录保存在链接在一起的数据库中?

时间:2009-09-11 05:58:13

标签: database c#-3.0

我有一个要求,我认为必须在世界各地频繁发生。我有两条链接在一起的记录,每当对它们进行更改时,都会创建一对新记录并保留相同的链接。

我正在处理的要求与保险行业有关,要求我停用当前的保单并在新行中重新激活它们,以显示保险单变更的历史记录。当它们被重新创建时,它们仍然需要链接在一起。

此过程如何从数据库中的行视图开始工作的示例:

保险ID,保险类型,主保险ID,状态

1,Auto Insurance,null,Active

2,Wind Screen Insurance,1,Active

请注意,上述如何将第二行的主保险ID表示这些政策之间的链接,指向第一行的保险ID。

在我写的代码中,我正在逐个处理每个策略,所以在第一步之后我有以下内容:

1,汽车保险,null,无效

2,Wind Screen Insurance,1,Active

3,汽车保险,null,有效

当我处理第二个政策时,我得到以下内容:

1,汽车保险,null,非活动

2,风幕保险,1,无效

3,汽车保险,null,Active

4,风幕保险, 1 ,有效//需要3不是1

你会注意到,当我创建新的Window Insurance时,由于我们复制了旧行,我们最终将Master Id保险指向非活动行。

为了解决这个问题,我必须跟踪之前处理的策略的主保险ID,这导致了以下代码:

int masterInsuranceId = -1;
foreach(Policy policy in policyList)
{
    //copy the old policy so the new policy has 
    //the same details as the old one
    Policy newPolicy = policyManager.Copy(policy);

    //if the new policy is not the master insurance store 
    //the master its new master insuance
    if(newPolicy.MasterInsuranceId.HasValue)
    {
       newPolicy.MasterInsuranceId = masterInsuranceId; 
    }

    //save the details of the new policy
    policyManager.SavePolicy(newPolicy);

    //record the master id so we can update the master id 
    //reference on the next policy
    if(newPolicy.MasterInsuranceId == null)
    {
        masterInsuranceId = newPolicy.Id;
    }
    else
    {
        masterInsuranceId = -1;
    }

    //inactivate the current policy
    policy.Status = Inactive;
    policyManager.UpdatePolicy(policy);

}

有谁知道如何简化这个?确保两条记录保持相互关联的最佳方法是什么,即使记录每次更改记录的更改历史记录?

3 个答案:

答案 0 :(得分:2)

您使用的是哪种数据库架构?通常,这是应该存储关系的地方,我认为这应该在数据处理级别而不是代码中进行处理。

这是一个非常简化的建议

保险(< insurance_id>,姓名,描述)

insurance_item(< item_id>,< insurance_id>,姓名,说明)

insurance_item_details(< item_id>,< policy_id>,when_changed)

insurance__policy与insurance_item有1对多的关系。 insurance__item与insurance_item_details有一对多的关系。 insurance__item__details中的每一行代表政策的变化。

这样,SQL可以快速快速检索最新的两个项目

SELECT FROM insurance_item_details, insurance_item, insurance where
             insurance_item_details.item_id = insurance_item.item_id
             AND insurance_item.insurance_id = insurance.insurance_id
             ORDER BY when_changed
             LIMIT 1

或者您甚至可以检索历史记录。

(尚未尝试过SQL)

所以我们的想法是你不要复制insurance_item - 你有另一个表来存储将要更改的元素,并用它来打一个时间戳,表示该变化是一种关系。

我不是SQL大师(不幸),但您需要做的就是插入insurance_item_details表,而不是复制。从它看起来的样子来看,像你原来的例子一样制作副本似乎违反了2NF,我想。

答案 1 :(得分:0)

如果您的代码设计不好而且需要进行更改,您会重构吗?那你为什么不考虑重构糟糕的数据库设计呢?通过良好的设计,这可以在数据库中进行更多的处理。

如果您在数据密集型的保险行业工作,而且您的数据库设计和查询技能不强,我建议您优先考虑这样做。

答案 2 :(得分:0)

感谢所有提供答案的人。不幸的是,由于工作条件的原因,我无法实现数据库更改,并且因使用编码解决方案而陷入困境。

在周末花了一些时间来解决这个问题后,我想出了一个解决方案,我相信它会稍微简化代码,即使它仍然无法完美。

我将功能提取到一个新方法中,然后传递我希望新策略链接到的主策略。

Policy Convert(Policy policy, Policy masterPolicy)
{
    Policy newPolicy = policyManager.Copy(policy);

    //link the policy to it's master policy
    if(masterPolicy != null)
    {
        newPolicy.MasterPolicyId = masterPolicy.Id;
    }

    SavePolicy(newPolicy);

    //inactivate the current policy
    policy.Status = Inactive;
    policyManager.UpdatePolicy(policy);

    return newPolicy;
}

这允许我循环遍历所有策略并传入需要链接的策略,只要策略按正确的顺序排序...在我的情况下是按开始日期然后是主策略标识。

Policy newPolicy = null;
foreach(Policy policy in policyList)
{
    Policy masterPolicy = policy.MasterPolicyId.HasValue ? newPolicy : null;
    newPolicy = Convert(policy, masterPolicy);   

}

当所有的事情都说完了,代码不是那么少,但我相信它更容易理解,它允许转换个别政策。