将LINQ扩展到Nhibernate提供程序,结合Dynamic LINQ问题

mur*_*rki 6 .net c# linq nhibernate linq-to-nhibernate

我正在使用NHibernate 3.1.0,我试图通过使用BaseHqlGeneratorForMethod和扩展,DefaultLinqToHqlGeneratorsRegistryFabio的帖子中所解释的那样扩展LINQ提供程序.

例如,为了支持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));
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经注册使用

internal class CustomLinqToHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry
{
    public CustomLinqToHqlGeneratorsRegistry()
    {
        this.Merge(new ToStringGenerator());
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止这适用于"静态"查询,我可以像这样使用它:

var results = mSession.Query<Project>();
string pId = "1";
results = results.Where(p => p.Id.ToString().Contains(pId));
Run Code Online (Sandbox Code Playgroud)

这正确转换为SQL对应(使用SQL Server 2008)

where cast(project0_.Id as NVARCHAR(255)) like (''%''+@p0+''%'')
Run Code Online (Sandbox Code Playgroud)

当我尝试将它与Microsoft Dynamic LINQ库(在此Scott Guthrie的帖子中讨论)结合使用时出现问题,如下所示:

var results = mSession.Query<Project>();
string pId = "1";
results = results.Where("Id.ToString().Contains(@0)", pId);
Run Code Online (Sandbox Code Playgroud)

这会导致NotSupportedException,消息为" System.String ToString() "(这与我在实现上述类之前使用静态查询获得的消息完全相同).使用" NHibernate " 源和" NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitMethodCallExpression(MethodCallExpression expression) "中的StackTrace 抛出此异常.

那我在这里错过了什么?我做错了什么,或者需要做些什么才能支持这种情况?

Pat*_*aar 3

我有同样的问题并解决了它。
首先,我要感谢 murki 提供的信息,让我上路!

部分答案就在法比奥的帖子中。要解决这个问题,您必须在构造函数中使用 the 方法RegisterGenerator而不是方法。我的类的实现如下:MergeCustomLinqToHqlGeneratorsRegistryCustomLinqToHqlGeneratorsRegistry

public class CustomLinqToHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry
{
    public CustomLinqToHqlGeneratorsRegistry()
        : base()
    {
        MethodInfo toStringMethod = ReflectionHelper.GetMethodDefinition<int>(x => x.ToString());
        RegisterGenerator(toStringMethod, new ToStringGenerator());
    }
}
Run Code Online (Sandbox Code Playgroud)