달력

8

« 2019/8 »

  •  
  •  
  •  
  •  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

데이터가 제법 많은 목록에서 제목을 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






Posted by 돼지고기국밥