Manières de stocker un objet sur plusieurs publications

asp.net entity-framework postback

Question

Par souci d'argumentation, supposons que j'ai un formulaire Web qui permet à un utilisateur de modifier les détails de la commande. L'utilisateur peut exécuter les fonctions suivantes:

  • Modifier les détails d'expédition / de paiement (tout texte simple / liste déroulante)
  • Ajouter / Supprimer / Modifier des produits dans l'ordre - cela se fait avec une grille
  • Ajouter / Supprimer des pièces jointes

Les produits et les pièces jointes sont stockés dans des tables de base de données distinctes avec une clé étrangère à la commande.

Entity Framework (4.0) est utilisé comme ORM.

Je souhaite autoriser les utilisateurs à apporter les modifications souhaitées à la commande, et uniquement lorsqu'ils cliquent sur "Enregistrer", je souhaite valider les modifications apportées à la base de données. Ce n'est pas un problème avec les zones de texte / cases à cocher, etc., car je peux simplement compter sur ViewState pour obtenir les informations requises. Cependant, la grille présente un problème beaucoup plus important pour moi car je ne peux pas trouver un moyen simple et agréable de conserver les modifications apportées par l'utilisateur sans enregistrer les modifications dans la base de données. Stocker l'arborescence des objets Order dans Session / ViewState n'est pas vraiment une option que je souhaiterais utiliser, car les objets pourraient devenir très volumineux.

La question est donc la suivante: comment puis-je préserver les modifications apportées par l'utilisateur jusqu'à ce qu'elles soient prêtes à «Enregistrer»?

Note rapide - J'ai cherché SO afin d'essayer de trouver une solution, mais je n'ai trouvé que des suggestions pour utiliser Session et / ou ViewState - deux solutions que je préférerais ne pas utiliser en raison de la taille potentielle de mes arbres d'objets

Réponse acceptée

Si utiliser la session n'est pas votre solution préférée, ce qui est probablement judicieux, la meilleure solution serait de créer vos propres tables de base de données temporaires (ou comme d'autres l'ont mentionné, d'ajouter un indicateur temporaire à vos tables de base de données existantes) et d'y conserver les données , stockant un identifiant unique dans la session (ou dans un cookie) pour une récupération ultérieure.


Réponse d'expert

Quelle taille considérez-vous comme grande? Si vous parlez de session-state (il ne revient donc pas à l'utilisateur réel, comme view-state), alors l'état est souvent une très bonne option. Tout sauf le fournisseur d'état en cours de processus utilise la sérialisation, mais vous pouvez influencer la façon dont il est sérialisé. Par exemple, j’aurais tendance à créer un modèle local qui représente uniquement l’état qui m’intéresse (plus toute information id / rowversion) pour cette opération (plutôt que les entités de domaine complètes, qui peuvent avoir une surcharge supplémentaire).

Pour réduire davantage la surcharge de la sérialisation, je souhaiterais utiliser quelque chose comme Protobuf-Net; cela peut être utilisé comme implémentation pour ISerializable , permettant ainsi la ISerializable d' ISerializable très légers (généralement beaucoup plus petits que BinaryFormatter , XmlSerializer , etc.), qui sont peu coûteux à reconstruire lors des requêtes de page.

Une fois la page enregistrée, je mettrais à jour les entités de mon domaine à partir du modèle local et soumettrais les modifications.

Pour info, pour utiliser un objet attribué Protobuf-net avec les sérialiseurs d'état (généralement BinaryFormatter ), vous pouvez utiliser:

// a simple, sessions-state friendly light-weight UI model object
[ProtoContract]
public class MyType {
    [ProtoMember(1)]
    public int Id {get;set;}

    [ProtoMember(2)]
    public string Name {get;set;}

    [ProtoMember(3)]
    public double Value {get;set;}
    // etc

    void ISerializable.GetObjectData(
        SerializationInfo info,StreamingContext context)
    {
        Serializer.Serialize(info, this);
    }

    public MyType() {} // default constructor

    protected MyType(SerializationInfo info, StreamingContext context)
    {
        Serializer.Merge(info, this);
    }
}


Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow