我想我在實現LinqToHql生成器類時缺少一些基本的東西。NHibernate LinqToHqlGenerator for SQL Server 2008全文索引'Containing'關鍵字
我已經成功註冊2008 contains
查詢使用自定義的方言有註冊在SQL Server:
RegisterFunction("contains", new StandardSQLFunction("contains", null));
我只是要查詢一個類全文索引:
public class SearchName
{
public virtual Guid Id {get; set;}
public virtual string Name {get; set;} // this is the search field
}
包含功能在HQL中正常工作:
var names = Session.CreateQuery("from SearchName where contains(Name,:keywords)")
.SetString("keywords", "john")
.List();
和生成的SQL是完美的:
select searchname0_.Id as Id4_,
searchname0_.Name as Name4_
from Search_Name searchname0_
where contains(searchname0_.Name, 'john' /* @p0 */)
下一個挑戰是實施LINQ到HQL發生器:
public class MyLinqtoHqlGeneratorsRegistry :
DefaultLinqToHqlGeneratorsRegistry
{
public MyLinqtoHqlGeneratorsRegistry()
{
this.Merge(new ContainsGenerator());
}
}
public class ContainsGenerator : BaseHqlGeneratorForMethod
{
public ContainsGenerator()
{
SupportedMethods = new[] {
ReflectionHelper.GetMethodDefinition<SearchName>(d => d.Name.Contains(String.Empty))
};
}
public override HqlTreeNode BuildHql(MethodInfo method,
System.Linq.Expressions.Expression targetObject,
ReadOnlyCollection<System.Linq.Expressions.Expression> arguments,
HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
{
return treeBuilder.MethodCall("contains",
visitor.Visit(targetObject).AsExpression(),
visitor.Visit(arguments[0]).AsExpression()
);
}
}
}
調用這樣的方法:
var namesLinq = Session.Query<SearchName>().Where(x=> x.Name.Contains("john")).ToList();
不幸的是,這似乎沒有覆蓋內置的Contains
方法,並且生成的SQL是錯誤的:
select searchname0_.Id as Id4_,
searchname0_.Name as Name4_
from Search_Name searchname0_
where searchname0_.Name like ('%' + 'john' /* @p0 */ + '%')
是不可能重寫默認的Contains
方法,還是我犯了一個愚蠢的錯誤?
PS - 我使用NHibernate 3.3.1.4000
有可能是另一種方法來取,你看到這篇博客的HTTP ://fabiomaulo.blogspot.co.uk/2010/07/nhibernate-linq-provider-extension.html - 顯示如何擴展LINQ提供程序(您可能無法將「Contains」作爲已註冊的函數進行覆蓋) – Rippo
@ Rippo是的,我看過那篇文章。它提供了我用來創建自己的擴展的大部分信息。 –
我在說的是你可能需要拿出另一個方法名來代替'Contains'來使用'FullTextContains',因爲Fabio正在使用'IsLike'來轉換爲'%foo%' – Rippo