Scenario:

image 

un dominio molto banale mappato su una singola tabella con una colonna che fa da discriminante, è così, è legacy e me lo devo tenere :-).

Adesso il nostro simpatico utente vuole fare una ricerca per tutti i Subject, a prescindere dal fatto che siano Company o Person, che contengono in Subject.Name qualcosa tipo (Like) ‘%mauro%’: una sorta di full-text.

Banale direte voi:

var criteria = querySpec.Keywords
    .AsSqlServerKeywords()
    .Aggregate( session.CreateCriteria<Subject>(), ( a, kw ) =>
        a.Add( Restrictions.Like( "Name", kw, MatchMode.Exact ) )
    );

dove querySpec è una Specification<T> e AsSqlServerKeywords un banale extension method che data una lista di keywords con i carattery jolly “windows based” (* e ?) li parsa e li rimpiazza con gli equivalenti per Sql Server (% e _) e poi forza una Restrictions.Like con MatchMode a Exact in modo che il generatore di query di NHibernate non raddoppi i caratteri jolly.

Ok, peccato che la proprietà Name non sia mappata perchè non è prevista nello schema della tabella quindi ciccia… quella roba si schianta di brutto.

Grazie al solito onnipresente Marco De Sanctis però ho trovato una soluzione che definirei semplicemente fantastica. Osservate il mapping, fatto con Fluent NHibernate:

this.Map( s => s.Name )
    .FormulaIs( "mySchema.udf_SubjectName( Type, FirstName, LastName, CompanyName )" );

Mappiamo la proprietà su una User Defined Function di Sql Server che NHibernate brillantemente invocherà per ogni riga del result set permettendoci di avere il dato che ci serve ma soprattutto permettendo ad NHibernate di generarci delle query.

Fantastico! Non c’è altro da dire.

.m

Technorati Tags: ,