Question

J'essaie de sauvegarder une entité mappée à l'aide de NHibernate, mais mon insertion dans la base de données échoue car la table sous-jacente contient une colonne qui n'autorise pas les valeurs NULL et N'EST PAS mappée dans mon objet de domaine. La raison pour laquelle il n'est pas mappé, c'est parce que la colonne en question prend en charge une application héritée et n'a aucune pertinence pour mon application. Je souhaite donc ne pas polluer mon entité avec la propriété héritée.

Je sais que je pourrais utiliser un champ privé à l'intérieur de ma classe - mais cela me semble toujours désagréable. J'ai lu le fait que je peux utiliser un intercepteur NHibernate et remplacer la méthode OnSave () pour l'ajouter. dans la nouvelle colonne juste avant que mon entité soit sauvegardée. Cela s’avère difficile, car je ne sais pas comment ajouter une instance de Nhibernate.type.IType au paramètre types de la fonction OnSave de mon intercept.

Mon entité ressemble à peu près à ceci:

public class Client
{
    public virtual int Id { get; set; }
    public virtual int ParentId { get; set; }
    public virtual string Name { get; set; }
    public virtual string Phone { get; set; }
    public virtual string Email { get; set; }
    public virtual string Url { get; set; }
}

Et mon intercepteur

 public class ClientInterceptor : EmptyInterceptor
{

    public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)
    {
        if (entity is Client)
        {
            /*
              manually add the COM_HOLD column to the Client entity
            */
            List<string> pn_list = propertyNames.ToList();
            pn_list.Add("COM_HOLD");
            propertyNames = pn_list.ToArray();

            List<Object> _state = state.ToList();
            _state.Add(false);
            state = _state.ToArray();

            //somehow add an IType to types param ??

         }
         return base.OnSave(entity, id, state, propertyNames, types);
    }
}

Quelqu'un a-t-il des idées sur la manière de procéder correctement?

Était-ce utile?

La solution

Je ne peux pas dire avec certitude puisque je n’ai jamais fait cela (comme Stefan, je préfère également ajouter une propriété privée), mais pouvez-vous simplement ajouter un NHibernate.Type.BooleanType vers le tableau types ?

List<IType> typeList = types.ToList();
typeList.Add(new BooleanType());
types = typesList.ToArray();

MODIFIER

Oui, on dirait que vous avez raison. les types ont un constructeur internal . J'ai creusé et j'ai trouvé TypeFactory :

  

Les applications doivent utiliser statique   méthodes et constantes sur   NHibernate.NHibernateUtil si le   IType par défaut est assez bon. Par exemple, le TypeFactory devrait seulement   être utilisé lorsque la chaîne doit avoir une longueur de 300 au lieu de 255. À ce stade   NHibernate.String ne vous fournit pas le type informatique correct. Utilisez plutôt TypeFactory.GetString (300) et gardez un   variable locale contenant une référence à IType.

On dirait donc que ce que vous voulez, c'est NHibernateUtil :

  

Permet d'accéder à la gamme complète de   NHibernate types intégrés. J'écris   les instances peuvent être utilisées pour lier des valeurs   pour interroger des paramètres. Aussi une usine   pour les nouveaux blobs et clobs.

typeList.Add(NHibernateUtil.Boolean);

Autres conseils

Personnellement, je ne le ferais pas si compliqué. Je voudrais ajouter la propriété privée et lui attribuer une valeur par défaut - fini. Vous pouvez également considérer une valeur par défaut dans la base de données, vous n'avez rien d'autre à faire.

private virtual bool COM_HOLD 
{ 
  get { return false; } 
  set { /* make NH happy */ } 
}

Avant d’écrire un intercepteur, j’envisagerais d’écrire un déclencheur de base de données. Parce qu'avec l'Interceptor, vous êtes "polluant" votre couche d'accès aux données. Cela pourrait le rendre instable et vous pourriez avoir d'étranges problèmes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top