NHibernate
Tentando di aggiornare una entità persistita su una tabella di SQL Server dove è presente un trigger ottengo l'eccezione seguente e l'aggiornamento fallisce:
[NHibernate.AdoNet.TooManyRowsAffectedException] {"Unexpected row count: 2; expected: 1"} NHibernate.AdoNet.TooManyRowsAffectedException
A quanto pare il fatto che il trigger aggiorni un altro record fa sì che il db ritorni 2 come numero di record aggiornati, il che fa pensare ad NH che ci sia stato un errore. Non ho trovato opzioni che dicano a NH di non verificare il numero di record aggiornati; sembra che l'unica soluzione consista nel disabilitare il conteggio dei record modificati nel trigger (impostare SET NOCOUNT ON prima del comando...
Per testare in NUnit i metodi di persistenza (direttamente in Persistence o tramite provider e manager), siccome normalmente la classe SessionHelper carica la configurazione di NH leggendo dall'assembly in esecuzione, e siccome usando la gui di NUnit l'assembly in esecuzione è quello del progetto NUnit,
è necessario aggiungere al progetto di test un file di configurazione che sarà nella stessa directory del progetto NUnit collegato e che conterrà la configurazione per NH; nel progetto NUnit selezionare Project - Edit - Configurazione - File Name e indicare il nome del file di configurazione appena creato.
- installare, se necessario, NH
- aggiungere il progetto Persistence alla solution
- aggiungere a Persistence il riferimento a NHibernate.dll e ai progetti della solution necessari (BusinessObjetcts, ...)
- aggiungere al file di configurazione del progetto che verrà avviato la sezione per NH:
<configSections>
<section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<nhibernate>
<add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
<add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
<add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2005Dialect" />
<add key="hibernate.connection.connection_string" value="Server=localhost; Integrated Security=SSPI; Database=ComLog;" />
<add key="hibernate.default_schema" value="dbo" />
<!-- General -->
<add key="hibernate.use_proxy_validator" value="true"/>
<!-- SQL Generation -->
<add key="hibernate.max_fetch_depth" value="2"/>
<add key="hibernate.show_sql" value="false"/>
<add key="hibernate.connection.release_mode" value="on_close" />
<!-- Reflection Optimizer: null | lcg | codedom...
Situazione:
i file di mapping e le classi helper di NH stannno nel progetto Persistence a cui il progetto Web ed altri progetti fanno riferimento. Essendo diversi i progetti che utilizzano Persistence non si vuole duplicare la configurazione di NH per ognuno di essi, per cui si è deciso di non inserirla nel web.config ma in un file di configurazione presente in Persistence.
Pb1: il file di configurazione, normalmente, non segue il file assembly (che in fase di compilazione viene copiato nella directory del progetto "chiamante").
Soluzione: imposto Copy to output directory = copy always per il file di configurazione.
Pb2: la sessionFactory deve...
Il formato più conveniente è:
day.ToString(
"yyyy/MM/dd");
Non ho ancora avuto il tempo di comprendere a fondo la questione, però quando utilizzavo SaveOrUpdate per aggiornare un oggetto già oggetto dello stesso metodo un paio di volte, ottenevo l'eccezione indicata e il record nel db non veniva aggiornata con il Flush successivo. Usando invece SaveOrUpdateCopy, se l'oggetto è già presente nel contesto di persistenza, non viene generata l'eccezione ma viene aggiornato l'oggetto presente (ciò che io pensavo facesse SaveOrUpdate; a questo punto cosa fa SaveOrUpdate? E Update?)