在Nhibernate中的where条件内调用实例方法

时间:2013-01-21 21:15:07

标签: nhibernate fluent-nhibernate

我在TaskRepository中有这段代码:

public List<Task> GetActiveTasks()
    {

        return SessionContainer.Session
            .Query<Task>()
            .Where(t => t.IsActive())
            .ToList();
    }

这是Task Class

中的IsActive()方法
public virtual bool IsActive()                                 
{
 return States.ToList().Max().Name == "Active";
}

我的问题是GetActiveTasks()会返回NotSupportedException

有谁知道这个问题是什么?我认为不可能在Where谓词中调用实例方法。如果那是不可能的,有没有解决方法呢?我需要完成所有活动任务,但如果不是这样的话,我不知道该怎么做。

2 个答案:

答案 0 :(得分:1)

Query中给出的lambdas必须转换为sql。 NHibernate如何解释你实现的方法?它不能。但是,您可以将IsActive映射为公式属性并查询它。类似的东西:

Map(x => x.IsActive).Formula("(SELECT ... FROM (Select s.Name FROM States s WHERE s.task_id = Id ORDER BY Id desc LIMIT 1) maxState WHERE maxState.Name == Active)")

答案 1 :(得分:0)

一种选择是重构Task类,如下所示:

public static Expression<Func<Task, bool>> IsActiveExpr =
    (task) => task.States.Max().Name == "Active";
private static Func<Task, bool> _IsActiveCompiled = IsActiveExpr.Compile();

public virtual bool IsActive()                                 
{
    return IsActiveCompiled(this);
}

现在,您可以在LINQ查询中使用IsActiveExpr。

另一个选择是扩展NHibernate查询提供程序,以便它直接识别IsActive()方法。进行搜索,或查看我对此问题的回复:Lambda string as VARCHAR。但是可能需要注意避免重复逻辑。