2009-12-04 15 views
5

Chcę móc wywoływać niestandardową funkcję o nazwie "recent_date" jako część mojego HQL. W ten sposób: [Date] >= recent_date()Niestandardowa funkcja SQL dla dialektu NHibernate

Stworzyłem nowy dialekt, dziedzicząc z MsSql2000Dialect i określając dialekt dla mojej konfiguracji.

public class NordicMsSql2000Dialect : MsSql2000Dialect 
{ 
    public NordicMsSql2000Dialect() 
    { 
     RegisterFunction(
      "recent_date", 
      new SQLFunctionTemplate(
       NHibernateUtil.Date, 
       "dateadd(day, -15, getdate())" 
       ) 
      ); 
    } 
} 

var configuration = Fluently.Configure() 
.Database(
    MsSqlConfiguration.MsSql2000 
    .ConnectionString(c => ....) 
    .Cache(c => c.UseQueryCache().ProviderClass<HashtableCacheProvider>()) 
    .Dialect<NordicMsSql2000Dialect>() 
) 
.Mappings(m => ....) 
.BuildConfiguration(); 

Dzwoniąc recent_date() pojawia się następujący błąd: System.Data.SqlClient.SqlException: „recent_date” nie jest rozpoznawany nazwę funkcji

używam go w WHERE dla mapowanie HasMany jak poniżej.

HasMany(x => x.RecentValues) 
    .Access.CamelCaseField(Prefix.Underscore) 
    .Cascade.SaveUpdate() 
    .Where("Date >= recent_date()"); 

Czego mi tu brakuje?

Odpowiedz

3

Myślę, że Where to instrukcja SQL, a nie instrukcja HQL. Więc nie zna funkcji. Działa tylko w HQL, w zapytaniach lub filtrach.

+0

Niestety, o tym. Powinienem był wyraźnie powiedzieć, że "SELECT .... From SomeTable WHERE ...." był tylko przykładem. Nie używamy tej części w naszym kodzie. –

+1

Odpowiedzi mówią, że. Gdzie w twoim mapowaniu oczekuje się, że czysty SQL nie będzie jakąkolwiek formą HQL. – Rashack

1

Myślałem, że musisz poprzedzić swoją funkcję "dbo". kiedykolwiek go używałeś. Mam zwyczaj dialekt ma to:

RegisterFunction("dbo.isbounded", new SQLFunctionTemplate(NHibernateUtil.Double, "dbo.IsBounded(?1, ?2, ?3, ?4, ?5, ?6)")); 

To wówczas nazywano stosując

Expression.Sql("dbo.IsBounded(...)") 
+0

Dzięki. Ale czy to zadziała w przypadku HasMany, jak w powyższym przykładzie? Zgodnie z poniższym linkiem, gdzie = "" może zawierać tylko zwykły stary SQL. Musiałem wybrać inne rozwiązanie, ponieważ potrzebowałem funkcji, nad którą pracowałem. http://groups.google.com/group/fluent-nhibernate/browse_thread/thread/acd551226c351f77/edec6d52c12397d7?lnk=gst –

+0

Fakt otrzymania wyjątku SQL wskazuje, że NHibernate przekazuje go do silnika sql i dlatego nie jest to problem NHibernate z rozpoznaniem funkcji. Jako taki, powiedziałbym tak. Pod względem miejsca, w którym klauzule biorą tylko surowy sql; Jeśli tak jest, to nie powinieneś w ogóle rejestrować funkcji i po prostu wpisz "dbo.recent_date()" w swojej klauzuli where. – toxaq

+0

Nie sądzę, że to zadziała, ponieważ SQLite (według mojej wiedzy) nie obsługuje funkcji niestandardowych. Potrzebuję rozwiązania do pracy zarówno z MsSql i SQLite, a ja chciałem to zrobić na poziomie dialektu. Jakieś pomysły? –