데이터가 제법 많은 목록에서 제목을 LIKE 검색하는 경우,

혹은 공백을 포함한 문자열의 공백 제거 후 검색을 하는 경우,

속도 이슈가 발생한다. 


이런 경우 DBMS에서 제공하는 FullTextSearch 기능을 사용하면 훨씬 빠른 결과를 얻을 수 있다. 


그런데 Devexpress GridControl을 사용하는 경우.... 

AutoFilter에서 검색시 Filter 정보에는 

contains([검색필드명], N'검색어') 로 입력되며,


실제로 DBMS에서 실행되는 Query문을 확인해보면 

    (isnull(CharIndex(N'검색어', [검색필드명]), 0) > 0 


이런 식이다... 대략 낭패 OTL


어찌해야 AutoFilter에서  FullTextSearch를 사용할 수 있을까?


찾아보니 아래와 같이 ICustomFunctionOperatorFormattable 인터페이스를 구현한 클래스를 추가하면 가능하다는 것을 알았다.


< 구현 방법 >


1. ICustomFunctionOperatorFormattable 를 구현한 클래스를 생성한다.

이름 지정과 포멧 함수 구현이 핵심인 듯...

using System.Data;
using DevExpress.Xpo.DB;
using DevExpress.Data.Filtering;

public class FullTextContainsFunction : ICustomFunctionOperatorFormattable {
    #region ICustomFunctionOperator Members
    // Evaluates the function on the client 
    public object Evaluate(params object[] operands) {
        // Full text search is not available on the client and should not be used there 
        throw new NotImplementedException();
    }
    public string Name {
        get { return "FullTextContains"; }
    }
    public Type ResultType(params Type[] operands) {
        return typeof(bool);
    }
    #endregion
    #region ICustomFunctionOperatorFormattable Members
    // The function's expression to be evaluated on the server 
    public string Format(Type providerType, params string[] operands) {
        // This example implements the function for MS SQL databases only 
        if (providerType == typeof(MSSqlConnectionProvider))
            return string.Format("contains({0}, {1})", operands[0], operands[1]);
        throw new NotSupportedException(string.Concat("This provider is not supported: ", 
            providerType.Name));
    }
    #endregion
}


2. 프로그램 시작시 ICustomFunctionOperatorFormattable 를 구현한 클래스의 인스턴스를 CriteriaOperator에 커스텀 함수로 등록한다.


// program.cs 나 MainForm 에 추가한다.

CriteriaOperator.RegisterCustomFunction(new FullTextContainsFunction());



3. 그리고 필터에서 검색시 아래와 같이 필터를 입력한다.


CriteriaOperator.Parse("FullTextContains([필드명], '검색어')");




결과는 아주 잘 작동한다.


* 참고 : https://documentation.devexpress.com/CoreLibraries/3246/DevExpress-ORM-Tool/Examples/How-to-Implement-a-Full-Text-Search






반응형

+ Recent posts