扩展的LINQ to NHibernate的供应商,并结合动态的LINQ问题并结合、供应商、动态、问题

2023-09-03 02:05:36 作者:独获万千少女心

我使用NHibernate的3.1.0和我想要通过延长LINQ提供程序 BaseHqlGeneratorForMethod ,延长 DefaultLinqToHqlGeneratorsRegistry 在法比奥的帖子。

I'm using NHibernate 3.1.0 and I'm trying to extend the LINQ provider by using BaseHqlGeneratorForMethod and extending the DefaultLinqToHqlGeneratorsRegistry as explained in Fabio's post.

例如,为了支持的ToString()我创建了一个 ToStringGenerator 如下图所示。

For example, to support ToString() I've created a ToStringGenerator as below.

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());
    }
}

等。到目前为止,这个工程的静态的疑问,我可以用它是这样的:

etc. So far this works for "static" queries, I can use it like this:

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

这正确地转换到其对应的SQL(使用SQL Server 2008)

This translates correctly to its SQL counterpart (using SQL Server 2008)

where cast(project0_.Id as NVARCHAR(255)) like (''%''+@p0+''%'')

当我尝试使用它结合微软动态的LINQ库(在这斯科特Guthrie的帖子)是这样的:

The problem arises when I try to use it in combination with Microsoft Dynamic LINQ library (discussed in this Scott Guthrie's post) like this:

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

这导致 NotSupportedException异常与消息 System.String的ToString()(这是完全一样的消息我是在实施之前的静态查询得到类上面提到的)。此异常被抛出与源 NHibernate的,并与堆栈跟踪在的NHibernate.Linq.Visitors.HqlGeneratorEx$p$pssionTreeVisitor.VisitMethodCallEx$p$pssion(MethodCallEx$p$pssion EX pression)

This results in a NotSupportedException with a message of "System.String ToString()" (which was the exact same messages I was getting with the static queries before implementing the classes mentioned above). This exception is being thrown with a source of "NHibernate" and with the StackTrace at "at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitMethodCallExpression(MethodCallExpression expression)".

那么,我在这里丢失?我做了什么错了,还是需要采取什么行动​​来支持这个场景?

So what am I missing here? What have I done wrong, or what needs to be done to support this scenario?

推荐答案

我有同样的问题,并固定它。 首先我要感谢murki提供这让我对我的方式的信息!_爱答案部分在于法比奥的职位。为了解决这个问题,你必须使用 RegisterGenerator 而不是合并的方法 CustomLinqToHqlGeneratorsRegistry 的构造。我执行 CustomLinqToHqlGeneratorsRegistry 类如下:

I had the same problem and fixed it. At first I want to thank murki for providing the information which got me on my way! The answer lies partly in Fabio's post. To solve this issue you have to use the RegisterGenerator instead of the Merge method in the CustomLinqToHqlGeneratorsRegistry constructor. My implementation of the CustomLinqToHqlGeneratorsRegistry class is as follows:

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