데이터가 제법 많은 목록에서 제목을 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
public object Evaluate(params object[] operands) {
throw new NotImplementedException();
}
public string Name {
get { return "FullTextContains"; }
}
public Type ResultType(params Type[] operands) {
return typeof(bool);
}
#endregion
#region ICustomFunctionOperatorFormattable Members
public string Format(Type providerType, params string[] operands) {
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