Это даст вам очень простой пункт MATCH ... AGAINST
. Если вы хотите усложниться (больше аргументов, указав модификатор поиска), вам придется внести некоторые большие изменения. Надеюсь, это поможет вам начать работу, хотя:
Создать новый диалект и зарегистрировать простой MATCH (...) AGAINST (...)
функции:
public class CustomMySQLDialect : MySQLDialect
{
public CustomMySQLDialect()
{
this.RegisterFunction(
"matchagainst",
new SQLFunctionTemplate(
NHibernateUtil.Boolean,
"match (?1) against (?2)"));
}
}
Создать статический метод расширения на string
, что вы будете использовать в операторах LINQ:
public static class LinqExtensions
{
public static bool MatchAgainst(this string source, string against)
{
throw new NotImplementedException();
}
}
Создайте новый LINQ к классу генератора HQL, который связывает метод с функцией SQL мы зарегистрирован в пользовательском диалекта:
public class MatchAgainstGenerator : BaseHqlGeneratorForMethod
{
public MatchAgainstGenerator()
{
this.SupportedMethods = new[]
{
ReflectionHelper.GetMethod(() => LinqExtensions.MatchAgainst(null, null))
};
}
public override HqlTreeNode BuildHql(
MethodInfo method,
System.Linq.Expressions.Expression targetObject,
ReadOnlyCollection<System.Linq.Expressions.Expression> arguments,
HqlTreeBuilder treeBuilder,
IHqlExpressionVisitor visitor)
{
return treeBuilder.BooleanMethodCall(
"matchagainst",
arguments.Select(visitor.Visit).Cast<HqlExpression>());
}
}
Создание пользовательского LinqToHqlGeneratorsRegistry:
public class MyLinqToHqlRegistry : DefaultLinqToHqlGeneratorsRegistry
{
public MyLinqToHqlRegistry()
{
var generator = new MatchAgainstGenerator();
RegisterGenerator(typeof(LinqExtensions).GetMethod("MatchAgainst"), generator);
}
}
Используйте свой собственный диалект, и Linq в HQL реестре либо в файле cfg.xml или в коде:
var cfg = new Configuration()
.DataBaseIntegration(db =>
{
db.Dialect<CustomMySQLDialect>();
})
.LinqToHqlGeneratorsRegistry<MyLinqToHqlRegistry>();
Окончательно, используйте ваш метод расширения в запросе LINQ-to-NHibernate:
session.Query<Article>()
.Where(a => a.Body.MatchAgainst("configured"))
.ToList()
.Dump();
Это будет генерировать SQL, который выглядит следующим образом:
select
userquery_0_.Id as Id51_,
userquery_0_.Title as Title51_,
userquery_0_.Body as Body51_
from
articles userquery_0_
where
match (userquery_0_.Body) against ('configured');
Опять же, это не поможет, если у вас есть более сложные требования. Но, надеюсь, это, по крайней мере, хорошая отправная точка.
В случае кому-то интересно о том, как сделать эту поддержку более сложные сценарии, здесь есть проблемы, я думаю, вы бы столкнуться:
- Разделяя аргументы
MATCH
от тех AGAINST
.
- Регистрация пользовательской функции SQL с NHibernate, которая может принимать произвольное количество аргументов в разных местах
- Создание правильного языка HQL даже после решения двух вышеперечисленных вопросов.
спасибо. Позднее я просмотрю ваши учебники. –
Кроме того, гораздо лучшая идея просто создать новую функцию MatchAgainst() в linq вместо переопределения. –
Это действительно отличная работа. Расширяемость NHibernates - это ... –