2009-09-11 5 views
0

J'ai une exigence que je crois doit se produire très fréquemment dans le monde entier. J'ai deux enregistrements qui sont liés ensemble et chaque fois qu'une modification est apportée à eux, une nouvelle paire d'enregistrements doit être créée et conserver le même lien.Comment conserver facilement les enregistrements d'une base de données reliés entre eux?

L'exigence sur laquelle je travaille concerne le secteur de l'assurance, ce qui nécessite de désactiver les polices d'assurance actuelles et de les réactiver dans une nouvelle rangée afin de montrer l'historique des modifications apportées aux polices d'assurance. Quand ils sont recréés, ils doivent toujours être reliés entre eux.

Un exemple de la façon dont ce processus est destiné à travailler à la vue des lignes dans une base de données:

assurance Id, assurance type, Maître d'assurance Id, Statut

1, Assurance Auto, null, Active

2, l'assurance de l'écran du vent, 1, active

Remarque dans ce qui précède comment le lien entre ces politiques est désigné par le Maître d'assurance Id de la deuxième rangée pointant le l'assurance Id de la première rangée.

Dans le code que je vous écris, je suis en train de traiter chacune des politiques un à la fois si après la première étape, je donne les résultats suivants:

1, Assurance Auto, null, inactif

2 , l'écran du vent d'assurance, 1, active

3, assurance Auto, null, active

Lorsque je traite la deuxième politique que j'obtenir le fol mugissement:

1, Assurance Auto, null, inactif

2, l'assurance de l'écran du vent, 1, inactif

3, Assurance Auto, null, Active

4, Assurance de l'écran du vent , , Actif // doit être 3 non 1

Vous remarquerez que lorsque je crée la nouvelle fenêtre d'assurance que, puisque nous copions l'ancienne ligne, nous finissons par avec l'assurance Master Id pointant vers la ligne inactive.

Pour contourner ce problème, je dois garder une trace de l'ID d'assurance maître de la politique précédente qui a été traitée qui a conduit au code suivant:

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); 

} 

Est-ce que quelqu'un sait comment cela peut être simplifié? Quelle est la meilleure façon de s'assurer que deux enregistrements resteront liés les uns aux autres, même si un historique des changements est enregistré pour chaque changement apporté à l'enregistrement?

Répondre

0

Merci à tous ceux qui ont fourni des réponses. Malheureusement, en raison des conditions de travail, je suis incapable d'implémenter des changements de base de données et je suis bloqué en essayant de faire avec une solution de codage. Après avoir passé un peu de temps au cours du week-end sur ce problème, j'ai trouvé une solution qui, je crois, simplifie un peu le code, même s'il n'est pas encore parfait.

J'ai extrait la fonctionnalité dans une nouvelle méthode et transmis la stratégie principale à laquelle je veux que la nouvelle stratégie soit liée.

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; 
} 

Cela me permet de boucler puis à travers toutes les politiques et passer dans la politique qui doit être liée aussi longtemps que les politiques sont classés dans l'ordre ... qui dans mon cas est par date de début et puis par l'identifiant principal de la politique.

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

} 

Quand tout est dit et fait, il est tout ce que beaucoup moins de code, mais je crois qu'il est beaucoup plus compréhensible et permet des politiques individuelles à convertir.

2

Quel type de schéma de base de données utilisez-vous? Habituellement, c'est où la relation devrait être stockée et je pense que cela devrait être modifié au niveau du traitement des données plutôt que du code.

Voici une recommandation très simplifiée

assurance (< insurance_id>, nom, description)

insurance_item (< item_id>, < insurance_id>, nom, description)

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

assurance_politique a une relation de 1 à plusieurs wi th insurance_item. Un insurance__item a une relation de un à plusieurs avec insurance_item_details. Chaque ligne dans insurance__item__details représente un changement de politique.

De cette façon, un SQL peut récupérer rapidement rapidement les deux derniers articles

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 

Ou vous pouvez même récupérer l'histoire.

(Le SQL n'a pas été essayé)

L'idée est que vous ne pas faire double emploi insurance_item - vous avez une autre table pour stocker les éléments qui seraient modifiés, et gifler un horodatage avec elle représente ce changement comme une relation. Je ne suis pas un gourou SQL (malheureusement), mais tout ce que vous devez faire est d'insérer dans la table insurance_item_details, au lieu de faire des copies. De la façon dont il semble, faire des copies comme dans votre exemple original semble violer 2NF, je pense.

+0

Malheureusement, je ne connais pas beaucoup sql ou beaucoup sur le schéma de base de données ... et je ne serais pas autorisé à le changer même si je le voulais.Je crois fortement que ce serait mieux géré ailleurs où ... Je ne sais pas où ... – mezoid

+1

À mon humble avis, ce problème est dans le domaine de la relation d'entité. Vous pouvez le faire par code, mais je ne peux pas penser à une solution autre que celle que vous avez déjà. C'est pourquoi pour une application intensive en données, faites bien le schéma, et ce sera plus facile à partir de maintenant Extrakun

0

SI vous aviez une mauvaise conception de code et que vous aviez besoin de faire un changement, refactoriseriez-vous? Alors, pourquoi ne pas envisager de refactoriser une mauvaise conception de base de données? C'est quelque chose qui est mieux géré dans la base de données grâce à une bonne conception. Si vous travaillez dans l'industrie de l'assurance qui nécessite beaucoup de données et que vous n'avez pas de solides compétences en conception de bases de données et en interrogation, je vous suggère d'en faire une priorité.

+0

ouais, je sais. Malheureusement, la réalité est compliquée. J'ai demandé à recevoir plus de formation sur la base de données cette année ... mais pour ce qui est de refactoriser une mauvaise conception de base de données, on m'a dit que non, vous ne pouvez pas apporter de modifications à la base de données. arrêtez de faire les choses pour améliorer les choses et faites simplement votre travail. Bien que j'aimerais ... Je ne peux pas parce que personne avec des compétences ne me donne aucun soutien pour enquêter sur les possibilités ... – mezoid

+0

Cela ne semble pas vraiment une bonne situation de travail pour vous. Bonne chance! Ce n'est pas si difficile de faire ENF de base pour la base de données. – Extrakun

Questions connexes