我有一个要求,我认为必须在世界各地频繁发生。我有两条链接在一起的记录,每当对它们进行更改时,都会创建一对新记录并保留相同的链接。
我正在处理的要求与保险行业有关,要求我停用当前的保单并在新行中重新激活它们,以显示保险单变更的历史记录。当它们被重新创建时,它们仍然需要链接在一起。
此过程如何从数据库中的行视图开始工作的示例:
保险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);
}
有谁知道如何简化这个?确保两条记录保持相互关联的最佳方法是什么,即使记录每次更改记录的更改历史记录?
答案 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);
}
当所有的事情都说完了,代码不是那么少,但我相信它更容易理解,它允许转换个别政策。