Domanda

Sto cercando di salvare un'entità mappata usando NHibernate ma il mio inserimento nel database non riesce perché la tabella sottostante ha una colonna che non consente valori null e NON è mappata nel mio oggetto dominio. Il motivo per cui non è mappato è perché la colonna in questione supporta un'applicazione legacy e non ha rilevanza per la mia applicazione, quindi mi piacerebbe non inquinare la mia entità con la proprietà legacy.

So che potrei usare un campo privato all'interno della mia classe - ma questo mi sembra ancora brutto. Ho letto che posso usare un intercettore NHibernate e sovrascrivere il metodo OnSave () per aggiungere nella nuova colonna proprio prima che la mia entità venga salvata Ciò si sta rivelando difficile poiché non riesco a capire come aggiungere un'istanza di Nhibernate.type.IType al parametro types di OnSave del mio interceptor.

La mia Entità assomiglia approssimativamente a questo:

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

E il mio intercettore

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

Qualcuno ha qualche idea su come farlo correttamente?

È stato utile?

Soluzione

Non posso dirlo con certezza dal momento che non l'ho mai fatto (come Stefan, preferisco anche solo aggiungere una proprietà privata), ma puoi semplicemente aggiungere un NHibernate.Type.BooleanType all'array types ?

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

Modifica

Sì, sembra che tu abbia ragione; i tipi hanno un costruttore internal . Ho scavato e ho trovato TypeFactory :

  

Le applicazioni dovrebbero usare statica   metodi e costanti su   NHibernate.NHibernateUtil se il   IType predefinito è abbastanza buono. Ad esempio, TypeFactory dovrebbe solo   essere usato quando la stringa deve avere una lunghezza di 300 anziché 255. A questo punto   NHibernate.String non ti fornisce l'IType corretto. Utilizzare invece TypeFactory.GetString (300) e mantenere a   variabile locale che contiene un riferimento a IType.

Quindi sembra che ciò che vuoi sia NHibernateUtil :

  

Fornisce l'accesso all'intera gamma di   NHibernate tipi integrati. Io digito   le istanze possono essere utilizzate per associare i valori   per interrogare i parametri. Anche una fabbrica   per nuovi BLOB e BLOB.

typeList.Add(NHibernateUtil.Boolean);

Altri suggerimenti

Personalmente non lo farei così complicato. Aggiungerei la proprietà privata e gli assegnerei un valore predefinito - finito. Potresti anche considerare un valore predefinito nel database, quindi non devi fare nient'altro.

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

Prima di scrivere un intercettore per quello che prenderei in considerazione di scrivere un trigger di database. Perché con l'Interceptor stai "inquinando" il tuo livello di accesso ai dati. potrebbe renderlo instabile e tu potresti avere strani problemi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top