扩展NHibernate Linq提供程序

时间:2016-05-02 12:23:57

标签: c# linq nhibernate

可能有人提供一些示例来扩展Hibernate Linq Provider以请求whichever field [equals | lt | gt | notEquals ...] some_value。即:

this.session.Query<C>.Where(c => c.WhichEverField().Equals(1));

其中WhichEverField()将是一种扩展方法。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

这是我曾经写过的一个类,它允许你在查询中使用Convert.ToInt64():

public class ConvertToInt64HqlGenerator : BaseHqlGeneratorForMethod
{
    public ConvertToInt64HqlGenerator()
        : base()
    {
        this.SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition(() => Convert.ToInt64("")),
                                        ReflectionHelper.GetMethodDefinition(() => Convert.ToInt64(0)),
                                        ReflectionHelper.GetMethodDefinition(() => Convert.ToInt64(0M))};
    }

    public override HqlTreeNode BuildHql(MethodInfo method,
                                            Expression targetObject,
                                            ReadOnlyCollection<Expression> arguments,
                                            HqlTreeBuilder treeBuilder,
                                            IHqlExpressionVisitor visitor)
    {
        return treeBuilder.Cast(visitor.Visit(arguments[0]).AsExpression(),typeof(Int64));
    }
}

要使用它,您需要创建一个Registry类:

public class MyLinqToHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry
{
    public MyLinqToHqlGeneratorsRegistry()
        : base()
    {
        this.Merge(new ConvertToInt64HqlGenerator());
    }
}

并将其添加到您的配置中:

Fluently.Configure().Database(msSQLconfig)
                    .ExposeConfiguration(c => c.LinqToHqlGeneratorsRegistry<MyLinqToHqlGeneratorsRegistry>())

答案 1 :(得分:1)

如果有任何扩展可能性,您可以在此list中查看,以便达到您的目标。

但如果我正确理解你的问题,我怀疑这是可行的。我不知道任何db语法处理&#34;无论哪个列&#34;语义,所以我看不出怎样才能将具有这种语义的LINQ扩展转换为具有此语义的SQL查询(从开始还需要HQL扩展通过将LINQ查询转换为HQL)来工作。

如果您打算在LINQ扩展程序中直接处理该语义,方法是在其中生成许多or比较条件,那么对于我提议的c.WhichEverField().Equals(1),我看起来不可能。
然后你不仅需要使用像AlexDev answer这样的东西。但是,您还必须对HqlTree方法中的参数和非平凡的BuildHql建筑进行类型检查。
然后,它会失败,因为在您定义它的BuildHql扩展名为WhichEverField扩展名时,您将不知道必须对您进行哪种比较操作数。

也许使用c.WhichEverField(SomeComparisonTypeEnum.Equal, 1)扩展程序,你可以处理它,但无论如何这不是一件容易的事。
如果这可能会有所帮助,您可以找到更多扩展示例(来自我)here并遵循其他链接,但没有一个具有您需求的复杂程度。