Напишите ICriteria для CONTAINSTABLE (полнотекстовый поиск sql) - PullRequest
4 голосов
/ 23 декабря 2011

Мне нужно выполнить полнотекстовый поиск по нескольким таблицам, поэтому я использую функцию SqlServer CONTAINSTABLE, она отлично работает как SQL-запрос, но как мне переписать CONTAINSTABLE в NHibernate ICriteria.

SELECT DISTINCT CP.* FROM ContentPack CP
    INNER JOIN [Content] C ON CP.ContentPackId = C.ContentPackId

 INNER JOIN
     CONTAINSTABLE([Content], (Title, [Description]), 'Foo*') AS KEY_TBL
     ON C.Title = KEY_TBL.[KEY]

Мне нужно преобразовать этот SQL в критерии NHibernate , кто-нибудь может мне помочь?

Ответы [ 2 ]

5 голосов
/ 24 декабря 2011

Та же проблема, которую я также получил

Полнотекстовый поиск NHibernate + SqlServer

, и у меня не было никакого решения, поэтому я выбрал концепцию перехватчика, где

1) Я создал отдельные критерии для основной таблицы и присоединился к полнотекстовой таблице

2) Также создал пользовательский перехватчик для nhibernate, который заменит полнотекстовое имя таблицы на (select [key] as foreignkey,[rank] as rank FROM CONTAINSTABLE(full_text,full_text_col , 'Foo*'))

Код

Сгенерированный запрос

SELECT c.id,
        c.name,
        ft.id, 
        ft.rank 
FROM candidates c 
    INNER JOIN full_text ft ON ft.id  = c.fulltext_id 
ORDER BY rank

Запрос после перехвата

SELECT c.id,
        c.name,
        ft.id,
        ft.rank 
FROM candidates c 
    INNER JOIN (
            SELECT [KEY] AS id ,[rank] AS rank 
            FROM CONTAINSTABLE(full_text, full_text_col, 'Foo*')
               ) AS ft ON ft.id  = c.fulltext_id 
ORDER BY rank

**** DetachedCriteria ****

        DetachedCriteria candidateCriteria = DetachedCriteria.For<Candidate>();
        DetachedCriteria fullTextCriteria = candidateCriteria.CreateCriteria("FullText");  

Код перехватчика

public interface CustomInterceptor : IInterceptor, EmptyInterceptor
{
    private string fulltextString;
    public string FulltextString
    {
        get { return fulltextString; }
        set { fulltextString = value; }
    }
    SqlString IInterceptor.OnPrepareStatement(SqlString sql)
    {
        string query = sql.ToString();
        if (query.Contains("full_text"))
        {
            sql = sql.Replace("full_text", "(select [key] as foreignkey,[rank] as Rank FROM CONTAINSTABLE(full_text, full_text_col, '"+FulltextString+"')) AS ft'");
        }
        return sql;
    }
}

Сущность

таблица кандидатов

id int

имя строки

fulltext_id

таблица full_text содержит полнотекстовый индекс

id int

full_text_coltext

rank int // всегда null

Relation

Candidate - FullText (1-1)

OpenSession

CustomInterceptor custonInterceptor=new CustomInterceptor();
custonInterceptor.FulltextString="YourString";
sessionFactory.OpenSession(custonInterceptor);
2 голосов
/ 23 декабря 2011

Вы можете использовать именованные запросы

http://nhibernate.info/blog/2009/04/16/nhibernate-mapping-named-queries-lt-query-gt-and-lt-sql-query-gt.html

<sql-query name="MyQuery">
    <return alias="cp"
                    class="ContentPack"/>
    SELECT DISTINCT {cp.*}
    INNER JOIN [Content] C ON CP.ContentPackId = C.ContentPackId
    INNER JOIN
     CONTAINSTABLE([Content], (Title, [Description]), 'Foo*') AS KEY_TBL
     ON C.Title = KEY_TBL.[KEY]
</sql-query>
...