這會給你一個非常簡單的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 to 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 to 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');
同樣,如果你有更復雜的要求,這也無濟於事。但希望這至少是一個很好的起點。
如果有人想了解如何使這種支持更復雜的情況,這裏是我想你會碰到的問題:
- 參數從那些
AGAINST
分離到MATCH
。
- 使用NHibernate註冊一個自定義的SQL函數,可以在不同的地方使用任意數量的參數
- 即使在解決了上述兩個問題之後,也可以創建正確的HQL。
非常感謝。我將在稍後檢查你的教程。 –
此外,更好的主意,只是在linq而不是重寫包含一個新的函數MatchAgainst()。 –
這真的很棒。 NHibernates的可擴展性是... –