[英]Extending LINQ to Nhibernate provider, in combination with Dynamic LINQ problem
我正在使用 NHibernate 3.1.0 並且我正在嘗試通過使用BaseHqlGeneratorForMethod
並擴展DefaultLinqToHqlGeneratorsRegistry
來擴展 LINQ 提供程序,如Fabio 的帖子中所述。
例如,為了支持ToString()
,我創建了一個ToStringGenerator
,如下所示。
internal class ToStringGenerator : BaseHqlGeneratorForMethod
{
public ToStringGenerator()
{
SupportedMethods = new[]
{
ReflectionHelper.GetMethodDefinition<object>(x => x.ToString())
};
}
public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
{
return treeBuilder.Cast(visitor.Visit(targetObject).AsExpression(), typeof(string));
}
}
我已經注冊使用
internal class CustomLinqToHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry
{
public CustomLinqToHqlGeneratorsRegistry()
{
this.Merge(new ToStringGenerator());
}
}
等到目前為止,這適用於“靜態”查詢,我可以像這樣使用它:
var results = mSession.Query<Project>();
string pId = "1";
results = results.Where(p => p.Id.ToString().Contains(pId));
這可以正確轉換為 SQL 對應物(使用 SQL Server 2008)
where cast(project0_.Id as NVARCHAR(255)) like (''%''+@p0+''%'')
當我嘗試將它與 Microsoft Dynamic LINQ 庫(在此 Scott Guthrie 的帖子中討論)結合使用時,就會出現問題,如下所示:
var results = mSession.Query<Project>();
string pId = "1";
results = results.Where("Id.ToString().Contains(@0)", pId);
這會導致NotSupportedException帶有“ System.String ToString() ”消息(這與我在實現上述類之前通過 static 查詢得到的消息完全相同)。 此異常的來源為“ NHibernate ”,StackTrace 位於“ NHibernate.Linq.VisitorExpression.HqlGeneratorExpressionExpression .
那么我在這里缺少什么? 我做錯了什么,或者需要做什么來支持這種情況?
我遇到了同樣的問題並修復了它。
首先,我要感謝 murki 提供了讓我上路的信息!
答案部分在於法比奧的帖子。 要解決此問題,您必須在CustomLinqToHqlGeneratorsRegistry
構造函數中使用RegisterGenerator
而不是Merge
方法。 我對CustomLinqToHqlGeneratorsRegistry
class 的實現如下:
public class CustomLinqToHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry
{
public CustomLinqToHqlGeneratorsRegistry()
: base()
{
MethodInfo toStringMethod = ReflectionHelper.GetMethodDefinition<int>(x => x.ToString());
RegisterGenerator(toStringMethod, new ToStringGenerator());
}
}
這里有兩個定義明確的獨立階段:
由於您已確定 static 表達式運行良好,因此問題在於1。
如果您執行以下操作會發生什么?
var results = Enumerable.Empty<Project>().AsQueryable();
string pId = "1";
results = results.Where("Id.ToString().Contains(@0)", pId);
如果它失敗了,您將確認這是 Dynamic Linq 單獨的問題(即它不支持您輸入的表達式),因此您必須深入研究並修補它。
半相關: ToStringGenerator
看起來很有用; 你能為 NHibernate 提交補丁嗎? http://jira.nhforge.org
假設 class Project
的屬性Id
是Int32
,請嘗試在ToStringGenerator
class 中注冊相應的Int32.ToString()
方法。
...
public ToStringGenerator()
{
SupportedMethods = new[]
{
ReflectionHelper.GetMethodDefinition<object>(x => x.ToString()),
ReflectionHelper.GetMethodDefinition<int>(x => x.ToString()),
};
}
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.