2017-03-05 1 views
0

J'essaie d'embrasser complètement la séparation des préoccupations fournies par la méthodologie MVC, mais j'ai atteint quelque chose d'un barrage routier sur lequel j'aimerais avoir des conseils. Comment traitez-vous/où devez-vous placer le code pour les champs qui ne sont pas stockés dans le back-end de la base de données, mais peuvent en être dérivés directement? Par exemple, je peux avoir un modèle représentant une personne. Par exemple, je peux avoir un modèle représentant une personne. Les informations stockées peuvent inclure leur date de naissance. Évidemment, je peux calculer leur âge actuel à partir de cela, mais je ne l'aurais pas stocké dans la base de données. Maintenant, je veux traiter l'âge comme un champ lorsque j'accède à l'objet personne (peut-être en sélectionnant tout le monde à un certain âge) avec un Lambda. MAIS, si je mets le code dans le modèle, est-ce que je ne casse pas la séparation des préoccupations? Même si je le mets là, devrait-il être calculé quand on accède au champ via get, ou quand l'objet est créé? Qu'en est-il des changements à la date de naissance? L'âge doit-il refléter la nouvelle valeur immédiatement ou seulement lorsque l'enregistrement est réécrit? Supposons, pour des raisons de discussion, que le calcul prenne beaucoup de temps à traiter, nous voulons donc minimiser son utilisation.Champs calculés avec MVC

J'espère que la question a du sens!

+0

Un champ en lecture seule (un avec un 'get' et aucun' set') sur le modèle semble être l'endroit idéal pour mettre cette logique. As-tu essayé? Y a-t-il eu une erreur? – David

+0

Oui, et aucune erreur. Cependant, je ne sais pas à quelle fréquence les différentes fonctions Lambda interrogent le get? Que faire si je fais une sorte et il interroge sur chaque comparaison? Alors, sûrement, ma fonction get pourrait être appelée un nombre important de fois! En outre, j'essaie de trouver la façon «correcte» de le faire - donner la séparation des préoccupations. Si ce n'est pas "correct", y a-t-il un "meilleur"? – Paul

+0

Et quel est le problème avec ça? Si le calcul est significatif mais que le résultat change rarement, vous pouvez mettre en cache la valeur résultante dans une variable privée, puis invalider ce cache chaque fois que des éléments de données affectant le calcul sont modifiés. – David

Répondre

2

Étant donné que le champ Age sera uniquement affiché/nécessaire sur certaines vues, il est logique d'avoir cette propriété sur le modèle de vue correspondant. Vous pourriez avoir une fonction qui prendra une instance Person et calculera son âge. Donc, votre contrôleur pourrait ressembler à ceci:

public ActionResult Index(int id) 
{ 
    Person person = GetFromDB(id); 
    PersonViewModel viewModel = Map(person); 
    return View(viewModel); 
} 

et à l'intérieur de la méthode Map:

public PersonViewModel Map(Person person) 
{ 
    var result = new PersonViewModel(); 
    result.Age = GetAge(person.Dob); 
    ... some other fields 
    return result; 
} 

maintenant la propriété Age sera disponible à la vue correspondante et peut être consulté plusieurs fois sans recalcul.