c# - Extending LINQ to Nhibernate provider,结合Dynamic LINQ问题

标签 c# .net linq nhibernate linq-to-nhibernate

我使用的是 NHibernate 3.1.0,我正在尝试通过使用 BaseHqlGeneratorForMethod 和扩展 DefaultLinqToHqlGeneratorsRegistry 来扩展 LINQ 提供程序,如 Fabio's post 中所述。 .

例如,为了支持 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 库(在 this Scott Guthrie's post 中讨论)结合使用时出现问题,如下所示:

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

这会导致 NotSupportedException 出现消息“System.String ToString()”(这与我在实现之前通过静态查询获得的消息完全相同上面提到的类)。抛出此异常的源是“NHibernate”,StackTrace 位于“at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitMethodCallExpression(MethodCallExpression expression)”。

那么我在这里缺少什么?我做错了什么,或者需要做什么来支持这种情况?

最佳答案

我遇到了同样的问题并解决了它。
首先,我要感谢 murki 提供的信息,让我踏上了前进的道路!

答案部分在于 Fabio 的帖子。要解决此问题,您必须在 CustomLinqToHqlGeneratorsRegistry 构造函数中使用 RegisterGenerator 而不是 Merge 方法。我对 CustomLinqToHqlGeneratorsRegistry 类的实现如下:

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

关于c# - Extending LINQ to Nhibernate provider,结合Dynamic LINQ问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6267912/

相关文章:

c# - Asp.net C# 在数据插入数据库时​​显示捕获错误

c# - 如何将具有多个连接的 Linq 表达式转换为方法语法或检索选择索引?

.net - 如何在 WinForms 中获得类似 StackPanel 的布局

c# - 如何在c# linq中找到集合的最小差异对象

c# - LINQ 和 AutoMapper

.net - .Net4链接到EF的较早加载;也许像DataLoadOptions

c# - Selenium ChromeDriver 如何禁用消息 :"DevTools on ws

c# - 奇怪的tcp连接场景

.net - 为什么 IHttpAsyncHandler 在负载下会泄漏内存?

.net - 如何从一个类访问另一个类的私有(private)变量?